zoukankan      html  css  js  c++  java
  • 四、Silverlight中使用MVVM(四)——演练

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

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

                   

      功能很明确,当我们更改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的分离形式,我感觉对于程序的调试也比先前容易定位。

  • 相关阅读:
    计算机原理 3.4 补码一位乘法
    信号与系统 第二章(2.1)
    信号与系统(1.6、1.7)
    第17章 使用BIOS进行键盘输入和磁盘读写
    第16章 直接定址表
    聚类:主要聚类算法
    机器学习——输入空间、特征空间、输出空间
    机器学习——线性回归
    机器学习——梯度下降法
    深度学习——概率与信息论
  • 原文地址:https://www.cnblogs.com/liuguanghai/p/3225988.html
Copyright © 2011-2022 走看看