Silverlight中使用MVVM(4)

    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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章