这篇文章主要是使用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文件,增加如下声明
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>
二:更新数据
1.在新增Domain Service时 选中Enable Editing,选中后会自动生成CUD的方法。通过这些方法来更新数据。
2.新增一个编辑按钮到EmployeeList页面。放置这个Button在DataForm控件后面。
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,你可以在这里类中增加验证。
如何定义这些验证呢?在新增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生成。我们在这个文件加入下面的的代码:
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" });
}
}
}
[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; }
<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>
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
<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>
<dataForm:DataField Label="Gender">
<TextBox Text="{Binding Gender, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" />
</dataForm:DataField>
<dataForm:DataField Label="Salaried">
<CheckBox IsChecked="{Binding SalariedFlag, 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>
public partial class EmployeeRegistrationWindow : ChildWindow
{
public EmployeeRegistrationWindow()
{
InitializeComponent();
NewEmployee = new Employee();
addEmployeeDataForm.CurrentItem = NewEmployee;
addEmployeeDataForm.BeginEdit();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
addEmployeeDataForm.CommitEdit();
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
NewEmployee = null;
addEmployeeDataForm.CancelEdit();
this.DialogResult = false;
}
public Employee NewEmployee { get; set; }
}
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0">
<Button x:Name="addNewEmployee" Width="90" Height="23" Content="Add Employee" Margin="4,0,0,0" Click="addNewEmployee_Click"/>
</StackPanel>
private void addNewEmployee_Click(object sender, RoutedEventArgs e)
{
EmployeeRegistrationWindow addEmp = new EmployeeRegistrationWindow();
addEmp.Closed += new EventHandler(addEmp_Closed);
addEmp.Show();
}
void addEmp_Closed(object sender, EventArgs e)
{
EmployeeRegistrationWindow emp = (EmployeeRegistrationWindow)sender;
if (emp.NewEmployee != null)
{
OrganizationContext _OrganizationContext = (OrganizationContext)(employeeDataSource.DomainContext);
_OrganizationContext.Employees.Add(emp.NewEmployee);
employeeDataSource.SubmitChanges();
}
}
新增的时候会调用OrganizationService.cs中的InsertEmployee方法。我们可以自定义这个方法。
public void InsertEmployee(Employee employee)
{
// Modify the employee data to meet the database constraints.
employee.HireDate = DateTime.Now;
employee.ModifiedDate = DateTime.Now;
employee.VacationHours = 0;
employee.SickLeaveHours = 0;
employee.rowguid = Guid.NewGuid();
employee.ContactID = 1001;
employee.BirthDate = new DateTime(1967, 3, 18);
if ((employee.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(employee, EntityState.Added);
}
else
{
this.ObjectContext.Employees.AddObject(employee);
}
}
http://www.cnblogs.com/sonce/archive/2011/02/26/1965896.html