这篇文章主要是使用WCF RIA SERVICE实现对数据的新增,更新,删除(CUD)。
一:查看数据详情
接上面文章,我们已经实现了数据的列表展示,列表展示的数据的详细是有限的,所以需要做一个表单显示某个数据的详情。
1.我们需要用到Silverlight Tookit,可以从http://silverlight.codeplex.com/下载。Silverlight tookit提供了很多有用的控件,这里我们用到了DataForm控件,这个控件在程序集System.Windows.Controls.Data.DataForm.Toolkit.dll。复制这个DLL到HRApp项目的Libs文件夹,如果没有新建。
2.打开EmployeeList.xaml文件,增加如下声明
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
3.在EmployeeList页面的DataPager控件下面,加入下面的XAML。
<dataForm:DataForm x:Name="dataForm1" Header="Employee Information" AutoGenerateFields="False" AutoEdit="False" AutoCommit="False" CurrentItem="{Binding SelectedItem, ElementName=dataGrid1}" Margin="0,12,0,0"> <dataForm:DataForm.EditTemplate> <DataTemplate> <StackPanel> <dataForm:DataField Label="Employee ID"> <TextBox IsReadOnly="True" Text="{Binding EmployeeID, Mode=OneWay}" /> </dataForm:DataField> <dataForm:DataField Label="Login ID"> <TextBox Text="{Binding LoginID, Mode=TwoWay}" /> </dataForm:DataField> <dataForm:DataField Label="Hire Date"> <TextBox Text="{Binding HireDate, Mode=TwoWay}" /> </dataForm:DataField> <dataForm:DataField Label="Marital Status"> <TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" /> </dataForm:DataField> <dataForm:DataField Label="Gender"> <TextBox Text="{Binding Gender, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> </dataForm:DataField> <dataForm:DataField Label="Vacation Hours"> <TextBox Text="{Binding VacationHours, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> </dataForm:DataField> <dataForm:DataField Label="Sick Leave Hours"> <TextBox Text="{Binding SickLeaveHours, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> </dataForm:DataField> <dataForm:DataField Label="Active"> <CheckBox IsChecked="{Binding CurrentFlag, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> </dataForm:DataField> </StackPanel> </DataTemplate> </dataForm:DataForm.EditTemplate> </dataForm:DataForm>
4.运行程序,进入EmployeeList页面,在列表中选择一项,dataform会显示该条数据的详情。
二:更新数据
1.在新增Domain Service时 选中Enable Editing,选中后会自动生成CUD的方法。通过这些方法来更新数据。
2.新增一个编辑按钮到EmployeeList页面。放置这个Button在DataForm控件后面。
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0"> <Button x:Name="submitButton" Width="75" Height="23" Content="Submit" Margin="4,0,0,0" Click="submitButton_Click"/> </StackPanel>
3.处理按钮的单击事件。
private void submitButton_Click(object sender, RoutedEventArgs e) { employeeDataSource.SubmitChanges(); }
4.运行程序进入EmployeeList列表,你可以通过点击那个铅笔,这时DataForm处于编辑模式。对数据更改后,单击OK,结束编辑模式。单击Submit按钮保存数据。
5.有时候需要更新某个字段,需要在Domain Service新增一个自定义的方法。打开OrganizationService.cs文件,加入下面的自定义的方法
public void ApproveSabbatical(Employee current) { // Start custom workflow here this.ObjectContext.Employees.AttachAsModified(current); current.CurrentFlag = false; }
6.编译项目,然后打开EmployeeList.xaml,新增按钮ApprovalSabbatical。
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0"> <Button x:Name="submitButton" Width="75" Height="23" Content="Submit" Margin="4,0,0,0" Click="submitButton_Click"/> <Button x:Name="approveSabbatical" Width="115" Height="23" Content="Approve Sabbatical" Margin="4,0,0,0" Click="approveSabbatical_Click"/> </StackPanel>
private void approveSabbatical_Click(object sender, RoutedEventArgs e) { Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem); luckyEmployee.ApproveSabbatical(); employeeDataSource.SubmitChanges(); }
8.运行程序。
三:数据验证
DataForm控件有显示数据验证错误的功能,如验证Email格式不正确等。
如何定义这些验证呢?在新增Domain Service Class的类的导航中,选中Generate associated classes for metadata。新增后会生成OrganizationService.metadata.cs,你可以在这里类中增加验证。
打开这个类,为下面的两个属性增加验证的特性
[Required]
public string Gender { get; set; }
[Range(0, 70)]
public short VacationHours { get; set; }
四:自定义数据验证
.NET自带的数据验证是很有限的,这时我们需要自己定义我们需要的数据验证。
1.在HRApp.Web项目新增 一个Code File,名字是OrganizationService.shared.cs。每当我们以.share.cs结尾命名的文件名,都会在Generated_Code生成。我们在这个文件加入下面的的代码:
using System;
using System.ComponentModel.DataAnnotations;
namespace HRApp.Web
{
public static class GenderValidator
{
public static ValidationResult IsGenderValid(string gender, ValidationContext context)
{
if (string.Compare(gender,"M", StringComparison.CurrentCultureIgnoreCase)==0 ||
string.Compare(gender,"F",StringComparison.CurrentCultureIgnoreCase)==0)
return ValidationResult.Success;
else
return new ValidationResult("The Gender field only has two valid values 'M'/'F'", new string[] { "Gender" });
}
}
}
打开OrganizationService.metadata.cs,在Gender属性加上上面的特性:
[CustomValidation(typeof(HRApp.Web.GenderValidator), "IsGenderValid")]
[Required]
public string Gender { get; set; }
运行程序查看效果:
还有一种自定义验证的方法是使用特性。数据验证的特性都是集成于ValidationAttribute的。通过重写IsValid方法来实现自定义验证。同样我们新增一个以shared.cs结尾的类文件。如下面代码实现如上面代码同样的功能:
using System;
using System.ComponentModel.DataAnnotations;
namespace HRApp.Web
{
public class GenderAttribute : ValidationAttribute
{
public GenderAttribute()
{
this.ErrorMessage = "The Gender field only has two valid values 'M'/'F'";
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value is string)
{
if (string.Compare(value.ToString(), "M", StringComparison.CurrentCultureIgnoreCase) == 0 ||
string.Compare(value.ToString(), "F", StringComparison.CurrentCultureIgnoreCase) == 0)
return ValidationResult.Success;
else
return new ValidationResult(ErrorMessage, new string[] { "Gender" });
}
else
return new ValidationResult(ErrorMessage, new string[] { "Gender" });
}
}
}
五:新增
新增一个界面,用于录入员工信息。在HRApp项目,我们新增一个Silverlight Child Window 页面,名字是EmployeeRegistrationWindow.xaml。
引用下面的命名空间
using HRApp.Web;
增加下面的属性:
public Employee NewEmployee { get; set; }
打开EmployeeRegistrationWindow.xaml文件,我们隐藏这个窗体的关闭按钮,需要为此窗体加入下面的属性:
<controls:ChildWindow x:Class="HRApp.EmployeeRegistrationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Width="400" Height="300"
Title="EmployeeRegistrationWindow"
HasCloseButton="False">
</controls:ChildWindow>
这里需要用到DataForm控件,所以在XAML里面声明下这个控件所在的命名空间:
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
增加DataForm控件到EmployeeRegistrationWindow.xaml。
<dataForm:DataForm x:Name="addEmployeeDataForm" AutoGenerateFields="False" AutoCommit="True" AutoEdit="True" CommandButtonsVisibility="None">
<dataForm:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<dataForm:DataField Label="Login ID">
<TextBox Text="{Binding LoginID, Mode=TwoWay}" />
</dataForm:DataField>
<dataForm:DataField Label="National ID">
<TextBox Text="{Binding NationalIDNumber, Mode=TwoWay}" />
</dataForm:DataField>
<dataForm:DataField Label="Title">
<TextBox Text="{Binding Title, Mode=TwoWay}" />
</dataForm:DataField>
<dataForm:DataField Label="Marital Status">
<TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" />
</dataForm:DataField>