在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 2012-06-15 17:24  风中语者  阅读(4405)  评论(0)    收藏  举报