Silverlight中使用MVVM(4)—演练

转自http://www.cnblogs.com/626498301/archive/2010/08/20/1804155.html

Silverlight中使用MVVM(1)--基础 

    Silverlight中使用MVVM(2)—提高 

    Silverlight中使用MVVM(3)—进阶

    Silverlight中使用MVVM(4)—演练

 

     本来打算用MVVM实现CRUD操作的,这方面例子网上资源还挺多的,毕竟CRUD算是基本功了,因为最近已经开始学习Cailburn框架了,感觉时间

挺紧的,这篇就实现其中的更新操作吧。

      捕获        1 

  功能很明确,当我们更改DataGrid中的CheckBox时,将源中当前发生变化的数据项在界面上显示出来。我们仍然在前面项目的基础上实现这个功能

首先我们需要给实体Person类添加一个Bool的属性,因为这里我们只对这个属性值操作,所以对于age,name属性也就无必要实现更改通知了

 
  
        public class Person:INotifyPropertyChanged 
      { 
        public int age { get; set; } 
        public string name { get; set; } 
        private bool _isBoy; 
        public bool IsBoy 
        { 
            get { return _isBoy; } 
            set { _isBoy = value; 
            if (PropertyChanged != null) 
            { 
                PropertyChanged(this, new PropertyChangedEventArgs("IsBoy")); 
            } 
            } 
        } 
        public event PropertyChangedEventHandler PropertyChanged; 
      }

我们仍然从Persons中获取数据集合,这里我们因为操作时源集合将发生变化,所以这里我们继承了ObservableCollection<T>类

 
  
         public class Persons:ObservableCollection<Person> 
        { 
        public Persons() : base() 
        {          
        } 
        public new event PropertyChangedEventHandler PropertyChanged; 
        public new void Add(Person person) 
        { 
            //添加项时自动绑定,并且向上传递发生改变的属性 
            ((INotifyPropertyChanged)person).PropertyChanged += (obj, e) => 
            { 
                if (PropertyChanged != null) 
                { 
                    PropertyChanged(obj, new PropertyChangedEventArgs(e.PropertyName)); 
                } 
            }; 
            base.Add(person); 
        }             
        }

     这里的Persons类通过new关键字隐藏了ObservableCollection<Person>原来的事件和方法,在Persons类中这里我们还需要

添加一个获取源数据的集合

 
  
       public Persons GetPerson() 
        { 
            //获取数据源集合 
            Persons getAllpersons = new Persons();  
            for (int i = 1; i < 4; i++) 
            { 
                getAllpersons.Add(new Person() {age=i,name="Student"+i,IsBoy=true}); 
            } 
            return getAllpersons; 
        }

       现在对于Model我们已经完成了工作,下面就是修改ViewModel了,这个部分其实没有太大的变化

 
  
        public Persons GetPersons { get; set; } 
        public PageViewModel() 
        { 
            GetPersons = new Persons().GetPerson(); 
            //数据源发生变化时的操作 
            GetPersons.PropertyChanged += (obj, e) => 
            { 
                Person person = (Person)obj; 
                MessageBox.Show(string.Format("CurrentDetailes:{0},{1},{2}",person.name,person.age,person.IsBoy)); 
            }; 
        }

      我们对于这个GetPersons这个源集合进行了一个操作,就是当它的属性发生变化时执行一个动作,这里我们只是用对话框将当前项显示出来

     对于UI,我们仍然只是用之前的Xaml

 
  
        <data:DataGrid ItemsSource="{Binding GetPersons}"  AutoGenerateColumns="True" Height="200" HorizontalAlignment="Left" Name="dataGrid1"  />

      最后我们将View和Model都放入MainPage页面中

 
  
        <UserControl.Resources> 
        <vm:PageViewModel x:Key="model"></vm:PageViewModel> 
        </UserControl.Resources> 
        <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource model}"> 
        <viw:PageView></viw:PageView> 
        </Grid>

      好了,这样我们的功能就实现了。不过在这里我们还是可以考虑一点东西的,真实情况是我们的实体类不会只是一个,那么我们就要重复为每一个实体类实现 ObservableCollection<T> 类了,这时可能你已经想到用泛型了,我们把集合用泛型实现.

对于Persons类,我们将其改为泛型集合

 
  
       public class ViewModelCollection<T> : ObservableCollection<T> 
       { 
        public ViewModelCollection() : base() 
        { 
        } 
        public new void Add(T item) 
        { 
            ((INotifyPropertyChanged)item).PropertyChanged += new PropertyChangedEventHandler(ViewModelCollection_PropertyChanged); 
            base.Add(item); 
        } 
        public new event PropertyChangedEventHandler PropertyChanged; 
        void ViewModelCollection_PropertyChanged(object sender, PropertyChangedEventArgs e) 
        { 
            if (PropertyChanged != null) 
            { 
                PropertyChanged(sender, new PropertyChangedEventArgs(e.PropertyName)); 
            } 
        } }

ViewModel中:

 
  
        public ViewModelCollection<Person> GetPersons{get;set;} 
        public PageViewModel() 
        {         
            GetPersons = GetMan(); 
            //数据源发生变化时的操作 
            GetPersons.PropertyChanged += (obj, e) => 
            { 
                Person person = (Person)obj; 
                MessageBox.Show(string.Format("CurrentDetailes:{0},{1},{2}", person.name, person.age, person.IsBoy)); 
            }; 
        } 
         public static ViewModelCollection<Person> GetMan() 
        { 
            //获取数据源集合 
            ViewModelCollection<Person> getAllpersons = new ViewModelCollection<Person>(); 
            for (int i = 1; i < 4; i++) 
            { 
                getAllpersons.Add(new Person() { age = i, name = "Student" + i, IsBoy = true }); 
            } 
            return getAllpersons; 
        }

      整体上的是一致的,只不过之前,因为实体类单一,所以我一直将数据源固定在Model模块中的,那么用泛型之后,我就将这个获取数据源的行为就移动到对应的ViewModel中了,这样实现更为优雅一些。

      其实通过这个循序渐进的过程,很容易让人感觉的到,从开始到现在除非我们需求的改变,很少修改UI,几乎大部分重构或者修改都是在ViewModel中实 现,这个也的确让人体会到UI与逻辑分离带来的方便之处,同时经过MVVM的分离形式,我感觉对于程序的调试也比先前容易定位。

      的确,MVVM模式如果再结合一些主流的框架,可以完成许多丰富的功能,当然这已经是另一个话题了,这里仅仅实现了更新功能,关于MVVM模式的CRUD的完整实现可以参考网上的资源,也可以参考这篇文章

    

      代码下载:UpdateByMVVM VS2010+SL3

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值