微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

稳扎稳打Silverlight(56) - 4.0通信之与 WCF Data Services 进行通信

  [源码下载]

稳扎稳打Silverlight(56) - 4.0通信之与 WCF Data Services 进行通信

作者: webabcd
介绍
Silverlight 4.0 对 WCF Data Services 的支持
  • DataServiceCollection<T> - 继承自 ObservableCollection<T>,用于将 WCF Data Services 提供的数据绑定到 Silverlight 控件上,当数据发生变化时可提供通知

在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例
演示 Silverlight 4.0 与 WCF Data Services 之间的通信
1、服务端
MyWCFDataService.svc.cs

代码
@H_502_40@/* @H_502_40@
 * WCF Data Services - 用于提供基于 OData 协议的数据服务
 * OData 协议 - 开放数据协议(Open Data Protocol),其基于 REST-ful 协议,参考: http://www.odata.org/ @H_502_40@
  @H_502_40@*/

using  System;
using  System.Collections.Generic;
using  System.Data.Services;
using  System.Data.Services.Common;
using  System.Linq;
using  System.ServiceModel.Web;
using  System.Web;

namespace  Silverlight40.Web.Service
{
    
public   class  MyWCFDataService : DataService < Model.northwindEntities >
    {
        
public   static   void  InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule(
" * " , EntitySetRights.All);

            
@H_502_40@// @H_502_40@ 指定对 Products, Categories, Orders 启用服务端分页,页大小为 3 @H_502_40@
            config.SetEntitySetPageSize( " Products " 3 );
            config.SetEntitySetPageSize(
" Categories " 3 );
            config.SetEntitySetPageSize(
" Orders " 3 );

            config.DataServiceBehavior.MaxProtocolVersion 
=  DataServiceProtocolVersion.V2;
        }
    }
}

2、客户端
Demo.xaml

代码
< navigation:Page  x:Class ="Silverlight40.WCFDataServices.Demo"  
           xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
           xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"  
           xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
           xmlns:navigation
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           xmlns:sdk
="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
           Title
="Demo Page" >
    
< Grid  x:Name ="LayoutRoot" >
        
< StackPanel  Orientation ="Vertical"  HorizontalAlignment ="Left" >

            
@H_502_40@<!-- @H_502_40@
                    用于演示通过 WCF Data Services 实现数据的增删改查
                 @H_502_40@-->
            
< StackPanel  Orientation ="Horizontal" >
                
< Button  Name ="btnGetData"  Content ="获取数据"  Margin ="5"  Click ="btnGetData_Click"   />
            
</ StackPanel >

            
< TextBlock  Text ="产品类别列表:"  Margin ="5"   />
            
< sdk:DataGrid  Name ="gridCategory"  Margin ="5"  Height ="200"  Width ="400"  AutoGenerateColumns ="False"  ItemsSource =" {Binding} "  
                       SelectionChanged
="gridCategory_SelectionChanged" >
                
< sdk:DataGrid.Columns >
                    
< sdk:DataGridTextColumn  Header ="类别ID"  Binding =" {Binding CategoryID} "  IsReadOnly ="True"   />
                    
< sdk:DataGridTextColumn  Header ="类别名称"  Binding =" {Binding CategoryName} "   />
                
</ sdk:DataGrid.Columns >
            
</ sdk:DataGrid >

            
< TextBlock  Text ="产品列表:"  Margin ="5"   />
            
< sdk:DataGrid  Name ="gridProduct"  Margin ="5"  Height ="200"  Width ="400"  AutoGenerateColumns ="False"  ItemsSource =" {Binding} "   >
                
< sdk:DataGrid.Columns >
                    
< sdk:DataGridTextColumn  Header ="产品ID"  Binding =" {Binding ProductID} "  IsReadOnly ="True"   />
                    
< sdk:DataGridTextColumn  Header ="产品名称"  Binding =" {Binding ProductName} "   />
                    
< sdk:DataGridTextColumn  Header ="单价"  Binding =" {Binding UnitPrice} "  IsReadOnly ="True"   />
                
</ sdk:DataGrid.Columns >
            
</ sdk:DataGrid >

            
< Button  Name ="btnSave"  Content ="保存"  Margin ="5"  Width ="400"  Click ="btnSave_Click"   />



            
@H_502_40@<!-- @H_502_40@
                    用于演示 WCF Data Services 的服务端分页
                 @H_502_40@-->
            
< TextBlock  Text ="订单列表:"  Margin ="5,20,5,5"   />
            
< sdk:DataGrid  Name ="gridOrder"  Margin ="5"  Height ="200"  Width ="400"  IsReadOnly ="True"  AutoGenerateColumns ="False"  ItemsSource =" {Binding} "   >
                
< sdk:DataGrid.Columns >
                    
< sdk:DataGridTextColumn  Header ="订单ID"  Binding =" {Binding OrderID} "   />
                    
< sdk:DataGridTextColumn  Header ="客户ID"  Binding =" {Binding CustomerID} "   />
                
</ sdk:DataGrid.Columns >
            
</ sdk:DataGrid >
            
< TextBlock  Name ="txtCurrentPageIndex"   />
            
< Button  Name ="btnPrev"  Content ="上一页"  Margin ="5"  Width ="400"   />
            
< Button  Name ="btnNext"  Content ="下一页"  Margin ="5"  Width ="400"   />

        
</ StackPanel >
    
</ Grid >
</ navigation:Page >

Demo.xaml.cs

代码
@H_502_40@/* @H_502_40@
 * 演示 Silverlight 4.0 与 WCF Data Services 之间的通信
 * 
 * DataServiceCollection<T> - 继承自 ObservableCollection<T>。用于将 WCF Data Services 提供的数据绑定到 Silverlight 控件上,当数据发生变化时可提供通知
 *     LoadAsync(IQueryable<T>) - 从数据服务上异步加载 IQueryable<T> 数据到 DataServiceCollection<T> 中(在 LoadCompleted 触发之前不能再调用方法
 *     LoadAsync() - 当 DataServiceCollection<T> 表示为某实体的导航属性时,从数据服务上异步加载该数据(在 LoadCompleted 触发之前不能再调用方法
 *     LoadCompleted - 异步加载完成后所触发的事件
 *         LoadCompletedEventArgs - LoadCompleted 事件的事件参数
 *         LoadCompletedEventArgs.QueryOperationResponse - 获取数据服务对改查询操作的响应
 *             QueryOperationResponse.Error - 引发的异常
 *             QueryOperationResponse.Headers -  HTTP 的响应头
 *             QueryOperationResponse.Query - 对应的 DataServiceQuery(DataServiceQuery.RequestUri - 请求数据服务的 URI) 对象
 *             QueryOperationResponse.StatusCode - HTTP 的响应代码
 *     Continuation - 返回一个 DataServiceQueryContinuation<T> 对象,该对象封装了当前查询结果的下一页的 URI
 *         DataServiceQueryContinuation<T>.NextLinkUri - 当前查询结果的下一页的 URI
 *     LoadNextPartialSetAsync() - 加载下一页数据到 DataServiceCollection<T> 中
 * 
 * Silverlight 通过 ObservableCollection<T> 与 ADO.NET Data Services 1.0 进行通信详见  http://www.cnblogs.com/webabcd/archive/2009/03/12/1409281.html @H_502_40@
 * WCF Data Services(ADO.NET Data Services 1.5)新特性详见  http://www.cnblogs.com/webabcd/archive/2010/06/11/1756071.html @H_502_40@
  @H_502_40@*/

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Net;
using  System.Windows;
using  System.Windows.Controls;
using  System.Windows.Documents;
using  System.Windows.Input;
using  System.Windows.Media;
using  System.Windows.Media.Animation;
using  System.Windows.Shapes;
using  System.Windows.Navigation;

using  Silverlight40.MyWCFDataServiceReference;
using  System.Data.Services.Client;

namespace  Silverlight40.WCFDataServices
{
    
public   partial   class  Demo : Page
    {
        
private  northwindEntities _context;
        
private  DataServiceCollection < Category >  _categories;

        
public  Demo()
        {
            InitializeComponent();
        }

        
protected   override   void  OnNavigatedTo(NavigationEventArgs e)
        {
            
@H_502_40@// @H_502_40@ 指定数据服务地址 @H_502_40@
            _context  =   new  northwindEntities( new  Uri( " Service/MyWCFDataService.svc " , UriKind.Relative));

            _categories 
=   new  DataServiceCollection < Category > ();
            _categories.LoadCompleted 
+=   new  EventHandler < LoadCompletedEventArgs > (_categories_LoadCompleted);

            
@H_502_40@// @H_502_40@ 演示如何通过 WCF Data Services 做服务端分页 @H_502_40@
            ServerPagingDemo();
        }

        
@H_502_40@// @H_502_40@ 开始异步加载 Categories 数据 @H_502_40@
         private   void  btnGetData_Click( object  sender, RoutedEventArgs e)
        {
            gridCategory.DataContext 
=   null ;
            gridProduct.DataContext 
=   null ;

            
@H_502_40@// @H_502_40@ 加载 Categories 表中的全部数据 @H_502_40@
            var query  =  from c  in  _context.Categories select c;
            _categories.LoadAsync(query);

            btnGetData.IsEnabled 
=   false ;
        }

        
@H_502_40@// @H_502_40@ 异步加载 Categories 数据完成 @H_502_40@
         void  _categories_LoadCompleted( object  sender, LoadCompletedEventArgs e)
        {
            
if  (e.Error  ==   null )
            {
                
if  (_categories.Continuation  !=   null )
                {
                    
@H_502_40@// @H_502_40@ 在数据服务中 Categories 被服务端分页了,所以需要不断调用 LoadNextPartialSetAsync() ,以便加载全部的 Categories 数据 @H_502_40@
                    _categories.LoadNextPartialSetAsync();
                }
                
else
                {
                    gridCategory.DataContext 
=  _categories;
                    gridCategory.Selectedindex 
=   0 ;

                    btnGetData.IsEnabled 
=   true ;
                }
            }
            
else
            {
                MessageBox.Show(e.Error.ToString());
                btnGetData.IsEnabled 
=   true ;
            }
        }

        
@H_502_40@// @H_502_40@ 开始异步加载指定 Category 下的 Products 数据 @H_502_40@
         private   void  gridCategory_SelectionChanged( object  sender, SelectionChangedEventArgs e)
        {
            Category category 
=  gridCategory.SelectedItem  as  Category;

            
if  (category  !=   null )
            {
                
if  (category.Products.Count  ==   0 )
                {
                    category.Products.LoadCompleted 
+=   new  EventHandler < LoadCompletedEventArgs > (Products_LoadCompleted);

                    
try
                    {
                        
@H_502_40@// @H_502_40@ 加载实体的导航属性数据 @H_502_40@
                        category.Products.LoadAsync();
                    }
                    
catch  (InvalidOperationException ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                }
                
else
                {
                    gridProduct.DataContext 
=  category.Products;
                }
            }
        }

        
@H_502_40@// @H_502_40@ 异步加载 Products 数据完成 @H_502_40@
         void  Products_LoadCompleted( object  sender, LoadCompletedEventArgs e)
        {
            
if  (e.Error  ==   null )
            {
                DataServiceCollection
< Product >  products  =  sender  as  DataServiceCollection < Product > ;

                
if  (products.Continuation  !=   null )
                {
                    
try
                    {
                        products.LoadNextPartialSetAsync();
                    }
                    
catch  (InvalidOperationException ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                }
                
else
                {
                    gridProduct.DataContext 
=  products;
                }
            }
            
else
            {
                MessageBox.Show(e.Error.ToString());
            }
        }

        
@H_502_40@// @H_502_40@ 异步保存 Categories 中的被更新的数据(包括增删改),由于 Products 是 Category 的导航属性,所以相关的 Products 的数据的更新也会被保存 @H_502_40@
         private   void  btnSave_Click( object  sender, RoutedEventArgs e)
        {
            
try
            {
                
@H_502_40@/* @H_502_40@
                 * northwindEntities - 继承自 DataServiceContext,在 VS 中引用服务后会自动生成这个对象
                 *     DataServiceContext.BeginSaveChanges() - 将有变化的数据提交至数据服务端进行更新
                 *     DataServiceContext.EndSaveChanges() - 获取 BeginSaveChanges() 操作的结果,返回一个 DataServiceResponse 类型的对象
                  @H_502_40@*/

                _context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, 
null );
            }
            
catch  (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        
@H_502_40@// @H_502_40@ 数据被异步保存后 @H_502_40@
         private   void  OnChangesSaved(IAsyncResult result)
        {
            
bool  error  =   false ;

            
this .dispatcher.BeginInvoke(()  =>
            {
                
try
                {
                    DataServiceResponse response 
=  _context.EndSaveChanges(result);

                    
foreach  (ChangeOperationResponse changeResponse  in  response)
                    {
                        
if  (changeResponse.Error  !=   null )
                            error 
=   true ;
                    }

                    
if  ( ! error)
                    {
                        MessageBox.Show(
" 数据更新成功 " );
                    }
                    
else
                    {
                        MessageBox.Show(
" 数据更新失败 " );
                    }
                }
                
catch  (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            });
        }



        
private   int  _pageIndex  =   0 ;
        
private   int  _pageSize  =   3 ;

        
@H_502_40@// @H_502_40@ 演示如何通过 WCF Data Services 做服务端分页 @H_502_40@
         private   void  ServerPagingDemo()
        {
            BindOrder();

            btnNext.Click 
+=  (s, args)  =>
            {
                _pageIndex
++ ;
                BindOrder();
            };

            btnPrev.Click 
+=  (s, args)  =>
            {
                _pageIndex
-- ;
                BindOrder();
            };
        }

        
private   void  BindOrder()
        {
            txtCurrentPageIndex.Text 
=   " 当前页索引: "   +  _pageIndex.ToString();

            var query 
=  from o  in  _context.Orders select o;
            query 
=  query.Skip(_pageIndex  *  _pageSize).Take(_pageSize);
            DataServiceCollection
< Order >  orders  =   new  DataServiceCollection < Order > ();
            orders.LoadAsync(query);

            orders.LoadCompleted 
+=  (s, args)  =>
            {
                gridOrder.DataContext 
=  orders;
            };
        }
    }
}

OK
[源码下载]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐