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了嗎??還沒還沒,我們繼續看下一篇吧。