• [Silverlight]WCF RIA Services+Mef+MVVM实现CRUD(增删改查)示例


    做这个示例的目的是为了给学习Silverlight的童鞋一些参考,并希望和大家讨论相关的一些问题,让这个示例更完善。
    示例功能说明:实现了雇员的增删改查,雇员表(Employee)和部门表(Department)、雇员类型表(EmployeeType)有外键关联,并和字典表(DataDict)有字典关系

    示例参考说明:主要参考了Codeproject上的http://www.codeproject.com/KB/silverlight/IssueVisionForSilverlight.aspx中的相关文章和代码。
    示例采用技术说明:
    1、采用了WCF RIA Services来和服务器端传输数据,具体来说就是Silverlight项目类型中的WCF RIA Services 类库项目,因为这个更快捷。
    2、采用了MVVM设计模式来实现UI元素也UI界面逻辑分离,这个的好处地球人都知道。
    3、采用了MEF来对Model和ViewModel、ViewModel和View之间的相互依赖进行解耦。
    4、采用了Prism中的部分工具,例如采用CompositePresentationEvent来实现View和ViewModel,ViewModel和ViewModel之间的事件传递,采用NotificationObject作为ViewModel的基类,采用Prism自带的DelegateCommand。
    示例项目结构说明:

    1、RIAServicesLibrary 解决方案文件夹中是WCF RIA Services的两个项目,服务器端项目RIAServicesLibrary.Web为客户端提供DomainService,来实现实体的增删改查,客户

    端项目RIAServicesLibrary通过RiA数据服务链接调用RIAServicesLibrary.Web,实现MVVM中的Models层,并对服务端传递过来的实体进行扩展。
    2、SLWCFRIADemo主项目提供员工增删改查操作的所有相关View和ViewModel。
    3、SLWCFRIADemo.Common项目顾名思义是公共层,被RIAServicesLibrary和SLWCFRIADemo引用。

    在做这个Demo的过程中遇到的一些问题和解决办法:
    1、怎样在Datagrid的行上触发ViewModel中的Command?
    因Datagrid的ItemsSource指向ViewModel员工集合的属性,而编辑和删除Command是定义在ViewModel中的,所以在Datagrid中直接绑定编辑和删除Command是不起作用的,经查询

    Google得出如下解决办法:
    首先定义一个类DataContextProxy,故名思意是DataContext的代理类,代码如下:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;

    namespace SLWCFRIADemo.Controls
    {
    public class DataContextProxy : FrameworkElement
    {
    public DataContextProxy()
    {
    this.Loaded += new RoutedEventHandler(DataContextProxy_Loaded);
    }

    void DataContextProxy_Loaded(object sender, RoutedEventArgs e)
    {
    Binding binding
    = new Binding();
    if (!String.IsNullOrEmpty(BindingPropertyName))
    {
    binding.Path
    = new PropertyPath(BindingPropertyName);
    }
    binding.Source
    = this.DataContext;
    binding.Mode
    = BindingMode;
    this.SetBinding(DataContextProxy.DataSourceProperty, binding);
    }

    public Object DataSource
    {
    get { return (Object)GetValue(DataSourceProperty); }
    set { SetValue(DataSourceProperty, value); }
    }

    public static readonly DependencyProperty DataSourceProperty =
    DependencyProperty.Register(
    "DataSource", typeof(Object), typeof(DataContextProxy), null);


    public string BindingPropertyName { get; set; }

    public BindingMode BindingMode { get; set; }

    }

    }


    再在页面中引用这个代理类

      xmlns:my="clr-namespace:SLWCFRIADemo.Controls"

    并修改相关代码如下:

     <sdk:DataGridTemplateColumn Header="修改 \ 删除" Width="100">
                                                        
    <sdk:DataGridTemplateColumn.CellTemplate>
                                                            
    <DataTemplate>
                                                                
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
                                                                    
    <HyperlinkButton Margin="5"  Content="修改" Command="{Binding Source={StaticResource DataContextProxy},Path=DataSource.ModifyCommand}"/>
                                                                    
    <HyperlinkButton Margin="5" Content="删除" Command="{Binding Source={StaticResource DataContextProxy},Path=DataSource.DeleteCommand}"/>
                                                                
    </StackPanel>
                                                            
    </DataTemplate>
                                                        
    </sdk:DataGridTemplateColumn.CellTemplate>
                                                    
    </sdk:DataGridTemplateColumn>

    搞定!
    2、采用WCF RIA Services怎么处理字典表的问题。
    因雇员表和字典表无外键关系,要在DataGrid中显示雇员的性别,不能直接绑定字典表实体,需要在雇员实体中做如下扩展(该扩展在RIAServicesLibrary项目):

      private EntityRef<DataDict> employeeSexDict;
             [Association(
    "EmployeeSex_DataDict""EmployeeSex""DictValue", IsForeignKey = false)]
            
    public DataDict EmployeeSexDict
            {
                
    get
                {
                    
    if ((this.employeeSexDict == null))
                    {
                        
    this.employeeSexDict = new EntityRef<DataDict>(this"EmployeeSexDict"this.FilterEmployeeSexDict);
                    }
                    
    return this.employeeSexDict.Entity;
                }
                
    set
                {
                    DataDict previous 
    = this.EmployeeSexDict;
                    
    if ((previous != value))
                    {
                        
    this.ValidateProperty("EmployeeSexDict", value);
                        
    if ((previous != null))
                        {
                            
    this.employeeSexDict.Entity = null;
                        }
                        
    if ((value != null))
                        {
                            
    this.EmployeeSex = value.DictValue;
                        }
                        
    else
                        {
                            
    this.EmployeeSex = default(int);
                        }
                        
    this.employeeSexDict.Entity = value;
                        
    this.RaisePropertyChanged("EmployeeSexDict");
                    }
                }
            }
            
    private bool FilterEmployeeSexDict(DataDict entity)
            {
                
    if (this.EmployeeSex.HasValue)
                    
    return (entity.DictValue == this.EmployeeSex.Value);
                
    else
                    
    return false;
            }

    这样就可以直接绑定字典表实体了。
    大家对这个示例有什么问题或意见?

    更新(2011-05-31):根据Mainz的这篇http://www.cnblogs.com/Mainz/archive/2011/05/27/2059940.html,对代码进行了修改,将查找和分页放在了服务器端,Mainz的代码有点小Bug,我进行了改正,具体请参照最新代码。

  • 相关阅读:
    .net winForm 实现类似qq 弹出新闻
    创业11年,我填过的5个大坑!(转)
    java中基本类型封装对象所占内存的大小(转)
    Java中如何创建进程(转)
    javac
    深入剖析Java中的装箱和拆箱(转)
    敏捷开发流程总结
    解决ccSvcHst.exe CPU占用超50%的问题,及其缘由
    JSP/ Servlet常见的中文乱码原因
    黑马程序猿-面向对象-多态
  • 原文地址:https://www.cnblogs.com/xiaozhuang/p/2063186.html
Copyright © 2020-2023  润新知