上一篇:Silverlight 2 (beta1)数据操作(5)——使用LINQ to SQL进行数据CRUD操作(上)
在上一篇,我们完成了这个程序的前面部分,这一篇,我们继续下面的操作。
这个部分主要完成Silverlight客户端的操作,首先引用WCF服务,然后在Page页面中,我们使用DataGrid控件来实现对数据的绑定,另外,添加一个用户控件实现增加、删除、修改操作处理。下面一步一步来实现这些步骤吧。
第一步:引用WCF服务
第二步:添加一个用户控件
第三步:编辑用户控件界面
为了演示方面,我没有做任何的界面美化,仅仅把数据库相应的字段在TextBox上实现双向绑定,即在任何时候都可以同时更新源数据和目标。提供了保存,删除,添加按钮实现数据操作事件。
绑定代码像这样,类似的,可以写出其它的代码。
<TextBox x:Name="txtProductType" Text="{Binding ProductType, Mode=TwoWay}" />
第四步:编辑用户控件事件
这一步比较复杂,这里分小点讨论。为了调用WCF服务,先定义一下全局变量。
AcademeServiceClient academeSClient;
1.定义事件
由于实时需要Page页的DataGrid控件和用户控件的更新,这里引用事件委托机制,所以先对外定义一些公共的事件和绑定数据方法。在Page页上实现一些方法,比如添加、删除、更新数据之后刷新列表。
//添加Product事件 public delegate void ProductUpdatedHandler (object source, Product product); public event ProductUpdatedHandler ProductUpdated; //删除Product事件 public delegate void ProductDeletedHandler(object source); public event ProductDeletedHandler ProductDeleted; //编辑取消事件 public delegate void ProductEditCancelHandler(object source); public event ProductEditCancelHandler ProductEditCancel; //绑定数据方法 public void SetProduct(Product product) { this.DataContext = product; }
2.更新数据
这是保存按钮触发的事件,利用DataContext属性获取TextBox上面的值,异步调用SaveProduct方法实现更新和添加数据操作。这里更新和添加数据就是利用ProductID的值,添加数据的时候ProductID默认为0,不为0的时候就是更新数据,在SaveProduct方法中已经强调过了。
txtMessage.Text = "正在保存"; Product product = (Product)this.DataContext; academeSClient.SaveProductCompleted += new EventHandler<SaveProductCompletedEventArgs> (academeSClient_SaveProductCompleted); academeSClient.SaveProductAsync(product);
在完成调用方法后,给出了一些提示性的文字。调用ProductUpdated方法刷新列表。
void academeSClient_SaveProductCompleted (object sender, SaveProductCompletedEventArgs e) { txtMessage.Text = "更新成功"; ProductUpdated(this, e.Result); }
3.添加数据
点击添加按钮,新建Product 实例,然后点击保存按钮,实现保存操作,在保存事件中,既可以用于保存又可以用户新建。这里的添加数据事件仅仅给用户一个提示,但是需要保存到数据库,还需要点击上面的保存按钮。
if (btnAddNew.Content == "取消") { btnAddNew.Content = "添加"; btnDelete.IsEnabled = true; if (ProductEditCancel != null) ProductEditCancel(this); } else { Product product = new Product(); this.DataContext = product; btnDelete.IsEnabled = false; btnAddNew.Content = "取消"; }
4.删除数据
同添加数据一样,获取数据,然后异步调用DeleteProduct方法删除这条数据。
txtMessage.Text = "正在删除"; Product product=(Product)this.DataContext; academeSClient.DeleteProductCompleted+= new EventHandler<System.ComponentModel.AsyncCompletedEventArgs> (academeSClient_DeleteProductCompleted); academeSClient.DeleteProductAsync(product);
在完成调用之后,给出了一些提示。调用ProductUpdated方法刷新列表。
void academeSClient_DeleteProductCompleted (object sender, System.ComponentModel.AsyncCompletedEventArgs e) { txtMessage.Text = "删除成功"; if (ProductDeleted != null) ProductDeleted(this); }
第五步:编辑Page页面
1.前台页面
前台显示页面,非常简单,我就放置了DataGrid控件和一个用户控件。
<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="200"/> <RowDefinition Height="400"/> </Grid.RowDefinitions> <my:DataGrid x:Name="grdProducts" IsReadOnly="True" Margin="14" Grid.Row="0" AutoGenerateColumns="True" GridlinesVisibility="All" RowDetailsVisibility="Visible" SelectionChanged="grdProducts_SelectionChanged"/> <Academe:ProductDetail x:Name="ProductDetailShow" Grid.Row="1"/> </Grid>
2.查询数据
在Page()方法中,直接异步调用GetAllProducts方法获取数据,绑定到DataGrid控件上面。
academeSClient.GetAllProductsCompleted += new EventHandler<GetAllProductsCompletedEventArgs> (academeSClient_GetAllProductsCompleted); academeSClient.GetAllProductsAsync();
在完成调用之后,获取数据,绑定到控件上面。
void academeSClient_GetAllProductsCompleted(object sender, GetAllProductsCompletedEventArgs e) { Product[] products = e.Result; grdProducts.ItemsSource = products; }
3.SelectionChanged事件
当选中某一项时,触发这个事件,获取选中的项,调用用户控件对外提供的SetProduct方法绑定到TextBox上。
private void grdProducts_SelectionChanged (object sender, EventArgs e) { Product productEntity = (Product)grdProducts.SelectedItem; ProductDetailShow.SetProduct(productEntity); }
4.完善程序
接下来,我们还需要写一些事件完善这个程序,首先我们完成在用户控件中定义的三个公共的事件。
ProductDetailShow.ProductUpdated += new ProductDetail.ProductUpdatedHandler (ProductDetailShow_ProductUpdated); ProductDetailShow.ProductEditCancel += new ProductDetail.ProductEditCancelHandler (ProductDetailShow_ProductEditCancel); ProductDetailShow.ProductDeleted += new ProductDetail.ProductDeletedHandler (ProductDetailShow_ProductDeleted);
实现这些事件方法,这些方法就是起到刷新列表,获取选中项的作用。
void ProductDetailShow_ProductDeleted(object source) { //删除选中的Product,重新绑定数据源 List<Product> products = new List<Product> (grdProducts.ItemsSource as Product[]); products.Remove(grdProducts.SelectedItem as Product); grdProducts.ItemsSource = products.ToArray<Product>(); } void ProductDetailShow_ProductEditCancel(object source) { //获取选择的Product Product productEntity = (Product)grdProducts.SelectedItem; } void ProductDetailShow_ProductUpdated (object source, Product product) { //刷新列表 academeSClient.GetAllProductsAsync(); }
最后来个整个项目截图
本篇程序分为3层架构,在数据访问层LINQ to SQL,在Web Service层使用WCF,最后在客户端Silverlight完成调用。
这个Silverlight项目被我弄的好像复杂了,这下顺便学习了用户控件事件的调用,不过这样增强了用户体验,不像上几篇所说的,各个用户控件好像很独立,没有很好的结合起来。这仅仅提供这个方法很好的结合用户控件把这个程序整合的很完善了。最后说一下,这里全部的代码都贴出来了,大家只要按步骤来,可以完成这个程序的,源代码就不提供下载了,因为我这个项目在使用中,还在扩充。大家也可以扩充,比如在DataGrid中嵌套一些控件显示图片,类型等等。