運行結果和解決方案管理截圖如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace 完全數據綁定 { class Person : INotifyPropertyChanged//INotifyPropertyChanged是.net內置的接口,數據綁定會檢測DataContext是否實現了INotifyPropertyChanged,如果實現了就會監聽PropertyChanged這個屬性改變的事件 { private string name;//定義名字 private int age;//定義年齡 public string Name { get; set; } public int Age//定義年齡屬性 { get { return age;} set { this.age = value; if (PropertyChanged != null) { PropertyChanged(this,new PropertyChangedEventArgs("Age"));//觸發事件,參數說明:觸發對象,事件數據 } } } public event PropertyChangedEventHandler PropertyChanged;//實現接口,定義一個屬性改變事件 } }
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 完全數據綁定 { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { private Person p1 = new Person();//定義一個字段並初始化 public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { p1.Name = "紅馬車"; p1.Age = 24; txtName.DataContext = p1; txtAge.DataContext = p1; } //增加年齡 private void btnAdd_Click(object sender, RoutedEventArgs e) { p1.Age++; } //顯示年齡 private void btnShow_Click(object sender, RoutedEventArgs e) { MessageBox.Show(p1.Age.ToString()); } } }
可以說MVVM是專為WPF打造的模式, 也可以說MVVM僅僅是MVC的一個變種, 但無論如何, 就實踐而言, 如果你或你的團隊沒有使用"Binding"的習慣, 那麼研究MVVM就沒有多大意義.
VIEW:你的界面,就是XAML
VIEWMODEL:界面的業務邏輯,也就是以前的XAML.CS文件
MODEL:你的業務數據模型
根據上面的定義,你應該寫在VIEWMODEL上。兩個VIEW之間的數據傳遞在MVVM中一律通過DataContext屬性進行,DataContext在MVVM中至關重要!
MVVM的本質就是綁定,只是MVVM要求更嚴格,最正統的MVVM要求刪除XAML的所有控件編程ID。
自己寫MVVM非常容易出錯,我推薦用simplemvvmtoolkit.(項目在codeplex中)。它有兩個比較好用的地方,一個是屬性改變通知用lamda表達式,這樣當你用重構工具修改模型屬性後PropertyChange裡的屬性名也會跟著改,避免了直接寫屬性字符串引起的錯誤。
還一個是它提供一個全局事件總線,DataContext數據交換要求兩個ViewModel之間存在引用關系,但實際應用時不總是這樣(如日志收集器界面)。通過這玩意可以多個ViewModel訂閱事件,任意一個ViewModel發布事件其它訂閱事件的ViewModel就能處理事件了。
simplemvvmtoolkit一個小問題就是用它的EventToCommand去綁定UserControl沒效果,這一點mvvmlight(也在codeplex裡)的RelayCommand就沒問題,所以我做項目時一般是這兩個庫一起用。
通過simplemvvmtoolkit寫MVVM你可以先把View畫好、寫出ViewModel和Model的模型定義,模型綁定全部可通過blend用鼠標完成,不許動用一下鍵盤。綁定完了只要專心填ViewModel的業務邏輯即可。
這麼說吧,wpf裡的數據綁定就是給數據源(source)和顯示數據的綁定對象(target)建立一個關系。綁定模式呢一般有單向綁定和雙向綁定的(默認為單向綁定,且當數據源實現INotifyPropertyChanged接口時,數據源改變可以導致前台顯示改變)如果是雙向綁定呢,source和target只要有一方改變,另外一方也會隨之改變。樓主的例子中兩個窗口都是target,而父窗口列表裡selectedItem和子窗口的文本框綁定的應該是viewModel裡同一個對象。當子窗口target發生更改,它會通知到viewModel這個source,然後這個source呢,就會通知到主窗口這個target。啊,對了,一般情況下呢,觸發數據變化是“失去焦點”,就是你所謂的點擊確定按鈕讓子窗口文本框失去焦點的情況下。但如果在綁定的時候有設置UpdateSourceTrigger=PropertyChanged,那就會實現實時更改數據了。