標籤:style blog http color io ar strong sp div
由於我的DoubanFm在重新考慮之後,需要設定一個全域的CurrentSong,這個欄位要讓所有的VM都知道,而我同時又想把它作為我所有VM的共有屬性。而且我想盡量減少代碼的複製,提高重用。所以我做了以下的工作:(下面是我在WPF中的測試)
首先我們得熟悉MVVMlight架構
然後:
(1)基類一。抽象的VM的基類
abstract class MainViewModel : ViewModelBase
二。私人靜態,公有非靜態暴露,還有關鍵點:在屬性更改之後用 RaisePropertyChanged<T>把更改通過Messenger訊息發送出去
1 protected const string DataItemPropertyName = "DataItem"; 2 3 static private DataItem dataitem=null; 4 5 6 public DataItem DataItem 7 { 8 get 9 {10 return dataitem;11 }12 13 set14 {15 if (dataitem == value)16 {17 return;18 }19 20 var oldvalue=dataitem;21 dataitem = value;22 RaisePropertyChanged<DataItem>(DataItemPropertyName, oldvalue, value, true);23 }24 }三。為子類VM提供通用註冊訊息的方法
1 protected void RegisterVM(object vm) 2 { 3 Messenger.Default.Register<PropertyChangedMessage<DataItem>>(vm, 4 (message) => 5 { 6 if(message.PropertyName==DataItemPropertyName) 7 RaisePropertyChanged(DataItemPropertyName); 8 9 });10 11 }四。建構函式只在需要時給靜態欄位賦值(例子中只為null的靜態賦值)
1 protected MainViewModel(IDataService dataService) 2 { 3 _dataService = dataService; 4 _dataService.GetData( 5 (item, error) => 6 { 7 if (dataitem == null) 8 { 9 dataitem = item;//初始化靜態變數10 }11 });12 }(2)子類:
子類1
1 public ViewModel1(IDataService dd):base(dd)2 {3 RegisterVM(this);4 }
子類2
1 public class ViewModel2 :MainViewModel2 {3 4 5 public ViewModel2(IDataService dd):base(dd)6 {7 RegisterVM(this);8 }9 }
子類3
1 public class ViewModel3 : MainViewModel2 {3 4 public ViewModel3(IDataService dd)5 : base(dd)6 {7 RegisterVM(this);8 }9 }
Ioc註冊子類
SimpleIoc.Default.Register<ViewModel1>(); SimpleIoc.Default.Register<ViewModel2>(); SimpleIoc.Default.Register<ViewModel3>();
(3)效果
原頁面
屬性變動後
原始碼下載。
WPF中多視窗共用靜態屬性