WPF – MVVM (二)
上一篇講到利用Binding來讓View與ViewModel的繫結,還有ViewModel與Model的關係,但離整個MVVM還有一點點的距離,接下來,我們繼續看下去。 ( 感覺好像漫畫連載喔…放心我不會和某獵x一樣拖稿的。 )
Button事件處理
上一篇我們還沒實際處理按下Button的功能,這裡我們實際的處理一下吧。
下面是View的cs檔,我們會建立一個私有的屬性,這個屬性會利用base.context將XMAL那邊實例化的PostsViewModel傳回來,另外,傳回來的物件需要轉型一下;接下來,我們就可以撰寫Button的Click事件,在這邊,我們將新的值"SkyMVVM"這個Title名稱,傳給PostViewModel ( 實際上會寫回到Model裡面 ),當然這樣子Label是不會改變的。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPFMVVM { public partial class MainWindow : Window { PostsViewModel _postsViewModel; public MainWindow() { InitializeComponent(); _postsViewModel = (PostsViewModel)base.DataContext; } private void button1_Click(object sender, RoutedEventArgs e) { //這裡還沒辦法通知View,告訴View要更改Label的content _postsViewModel.PostsTitle = "SkyMVVM"; } } }
這邊,如果要Label改變,最直接的做法是在Button Click裡面再加上Label.Content = “SkyMVVM”這行,這樣就可以讓Label馬上的改變,但這樣做當然不好啊,第一,這樣就失去了Binding的意義了,第二,這樣做,Button Click就和Label有了很深的關係。
所以最好的做法是,當我們的PostViewModel的PostsTitle改變的時候,自動讓Label的Content去做改變,但要怎樣做呢?
INotifyPropertyChanged
登登豋登!沒錯我們就是要利用INotifyPropertyChanged這個介面,這個介面裡面含有一個PropertyChanged事件,此事件可以更新繫結的目標喔!
所以我們改寫一下ViewModel的程式碼,讓他實作InotifyPropertyChanged,並且寫一個Function ( RaisePropertyChanged ),此function會產生一個事件,並通知繫結的Label更改Content。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace WPFMVVM2 { //實作InotifyPropertyChanged public class PostsViewModel : INotifyPropertyChanged { public Posts posts{ get; set;} public event PropertyChangedEventHandler PropertyChanged; public PostsViewModel() { posts = new Posts { postsText = "", postsTitle = "Unknown" }; } public string PostsTitle { get { return posts.postsTitle; } set { if (posts.postsTitle != value) { posts.postsTitle = value; RaisePropertyChanged("postsTitle"); } } } //產生事件的方法 private void RaisePropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } }
做到此,我們就成功地讓ViewModel的屬性和Label進行分離了,也就是說ViewModel可以完全不用知道View了!但這樣就算完成MVVM了嗎??還沒還沒,我們繼續看下一篇吧。