zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    POJ 2923 Relocation (状态压缩,01背包)
    HDU 2126 Buy the souvenirs (01背包,输出方案数)
    hdu 2639 Bone Collector II (01背包,求第k优解)
    UVA 562 Dividing coins (01背包)
    POJ 3437 Tree Grafting
    Light OJ 1095 Arrange the Numbers(容斥)
    BZOJ 1560 火星藏宝图(DP)
    POJ 3675 Telescope
    POJ 2986 A Triangle and a Circle
    BZOJ 1040 骑士
  • 原文地址:https://www.cnblogs.com/lizhizhang/p/3698137.html
Copyright © 2011-2022 走看看