在Windows Phone平台上使用MVVM模式进行开发时,常遇到的一个问题是ViewModel间如何交互?比如存在这样一个问题,App里有A和B两个page,从A导航到B,然后点击back键返回到A,在这个过程中,B的ViewModel里面的数据如何传递给A? 因为this.NavigationService.GoBack()不支持参数的传递。这里介绍一种解决方案,即Meidator模式。
贴一些代码先:
这是一个Mediator类,采用了Singleton模式,只能生成一个实例对象,ViewModel间的数据交互就是使用这个类来实现的。
1 using System; 2 using System.Collections.Generic; 3 4 namespace MediatorTest.Mediator 5 { 6 /// <summary> 7 /// Available cross ViewModel messages 8 /// </summary> 9 public enum ViewModelMessages 10 { 11 MessageType1 = 1, 12 }; 13 14 /// <summary> 15 /// Provides loosely-coupled messaging between 16 /// various colleagues. All references to objects 17 /// are stored weakly, to prevent memory leaks. 18 /// </summary> 19 public class Mediator 20 { 21 #region Fields 22 private static Mediator _instance = new Mediator (); 23 24 Dictionary<ViewModelMessages , Action< Object>> internalList 25 = new Dictionary <ViewModelMessages, Action<Object >>(); 26 #endregion // Fields 27 28 #region Property 29 /// <summary> 30 /// The singleton instance 31 /// </summary> 32 public static Mediator Instance 33 { 34 get 35 { 36 return _instance; 37 } 38 } 39 #endregion 40 41 #region Ctor 42 //CTORs 43 static Mediator() {} 44 private Mediator() {} 45 #endregion // Constructor 46 47 #region Methods 48 public void Register(ViewModelMessages message, Action<object > callback) 49 { 50 internalList[message] = callback; 51 } 52 53 public void NotifyColleagues(ViewModelMessages message, object args) 54 { 55 if (internalList.ContainsKey(message)) 56 { 57 internalList[message].Invoke(args); 58 } 59 } 60 #endregion // Methods 61 } 62 }
在B的ViewModel里,如果数据发生变化,可调用Mediator类的实例广播消息,如下代码所示:
1 using System.ComponentModel; 2 using MediatorTest.Mediator; 3 4 namespace MediatorTest.ViewModels 5 { 6 public class B_ViewModel : INotifyPropertyChanged 7 { 8 #region Property 9 private string _text; 10 public string Text 11 { 12 get 13 { 14 return _text; 15 } 16 set 17 { 18 if (_text != value) 19 { 20 _text = value; 21 NotifyPropertyChanged("Text"); 22 Mediator.Mediator.Instance.NotifyColleagues( 23 ViewModelMessages.MessageType1, 24 value 25 ); 26 } 27 } 28 } 29 #endregion // Property 30 31 #region INotifyPropertyChanged 32 public event PropertyChangedEventHandler PropertyChanged; 33 34 protected void NotifyPropertyChanged(string propertyName) 35 { 36 if (PropertyChanged != null) 37 { 38 PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 39 } 40 } 41 #endregion // INotifyPropertyChanged 42 } 43 }
然后可以在A的ViewModel的构造函数里写如下代码来接受消息:
1 using System.ComponentModel; 2 using MediatorTest.Mediator; 3 4 namespace MediatorTest.ViewModels 5 { 6 public class A_ViewModel : INotifyPropertyChanged 7 { 8 #region Property 9 private string _text; 10 public string Text 11 { 12 get 13 { 14 return _text; 15 } 16 set 17 { 18 if (_text != value) 19 { 20 _text = value; 21 NotifyPropertyChanged("Text"); 22 } 23 } 24 } 25 #endregion // Property 26 27 #region Constructor 28 public A_ViewModel() 29 { 30 Mediator.Mediator.Instance.Register( 31 ViewModelMessages.MessageType1, 32 param => 33 { 34 Text = param as string; 35 }); 36 } 37 #endregion // Constructor 38 39 #region INotifyPropertyChanged 40 public event PropertyChangedEventHandler PropertyChanged; 41 42 protected void NotifyPropertyChanged(string propertyName) 43 { 44 if (PropertyChanged != null) 45 { 46 PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 47 } 48 } 49 #endregion // INotifyPropertyChanged 50 } 51 }
使用起来很简单吧!
posted on
浙公网安备 33010602011771号