深入介绍 MVVM Light Messenger相关代码小记

原文链接
https://learn.microsoft.com/zh-cn/archive/msdn-magazine/2014/june/mvvm-the-mvvm-light-messenger-in-depth
图1:发送和接收消息

public class Registration 
{
 public void SendUpdate() 
  { 
    var info = new RegistrationInfo { // ...一些属性 }; 
    Messenger.Default.Send(info); 
  } 
} 
public class RegisteredUser 
{ 
 public RegisteredUser() 
  { 
    Messenger.Default.Register<RegistrationInfo>( this, HandleRegistrationInfo); 
  } 
  private void HandleRegistrationInfo(RegistrationInfo info) 
  { 
     // 更新已注册的用户信息
  } 
} 
public class RegistrationInfo 
{ 
     // ...一些属性 
}

图 2:使用命名方法或 Lambda 进行注册

public UserControl() 
{ 
    InitializeComponent(); 
    // 使用命名方法进行注册 ---- 
    Loaded += Figure2ControlLoaded; 
    Messenger.Default.Register<AnyMessage>( this, HandleAnyMessage); 
    // 使用匿名 Lambda 进行注册 ---- 
    Loaded += (s, e) => {
    // 执行某操作 
    }; 
    Messenger.Default.Register<AnyMessage>( this, message => {
    // 执行某操作 
    }); 
} 
private void HandleAnyMessage(AnyMessage message) 
{ 
    // 执行某操作 
}
 private void Figure2ControlLoaded (object sender, RoutedEventArgs e) 
{ 
    // 执行某操作 
}

跨线程访问

public void RunOnBackgroundThread() 
{
     // 执行某后台操作
     DispatcherHelper.CheckBeginInvokeOnUI( () => { 
       Messenger.Default.Send(new ConfirmationMessage()); 
      }); 
}

图 3:实例之间的强引用

public class Setup 
{
    private First _first = new First(); 
    private Second _second = new Second(); 
    public void InitializeObjects() 
    { 
      _first.AddRelationTo(_second);
    } 
    public void Cleanup() 
    { 
      _second = null; // 即使 _second 实例设置为空,它也仍会保留在内存中,
      //因为引用计数不为零,_first 仍引用它
    } 
} 
public class First 
{ 
   private object _another; 
   public void AddRelationTo(object another) 
   { 
     _another = another; 
   } 
} 
public class Second { }

图 4:使用 WeakReference 实例

public class SuperSimpleMessenger 
{ 
    private readonly List<WeakReference> _receivers = new List<WeakReference>(); 
    public void Register(IReceiver receiver) 
    { 
      _receivers.Add(new WeakReference(receiver)); 
    } 
    public void Send(object message) 
    { 
      // 锁定接收端以免发生多线程问题。
      lock (_receivers) 
      { 
        var toRemove = new List<WeakReference>(); 
        foreach (var reference in _receivers.ToList()) 
        { 
            if (reference.IsAlive) 
              { 
                ((IReceiver)reference.Target).Receive(message); 
              }
           else 
             { 
               toRemove.Add(reference); 
             } 
        } 
        // 删除无效引用。
        // 在其他循环中执行此操作,以免在修改当前循环访问的集合时发生异常。 
        foreach (var dead in toRemove)
        { 
          _receivers.Remove(dead);
        } 
      } 
   } 
}

图 6:使用默认的 Messenger 并检查发送端

public class FirstViewModel 
{ 
     public FirstViewModel() 
     { 
        Messenger.Default.Register<NotificationMessage>( this, message => { 
        if (message.Sender is MainViewModel) 
          { 
            // 此消息是要发送给我。
          }
       }); 
     } 
}
public class SecondViewModel 
{ 
     public SecondViewModel() 
     { 
        Messenger.Default.Register<NotificationMessage>( this, message => { 
        if (message.Sender is SettingsViewModel) 
          {
           // 此消息是要发送给我 
          } 
       }); 
     } 
}

图 7:使用专用 Messenger

public class MainViewModel 
{ 
      private Messenger _privateMessenger; 
      public MainViewModel() 
      { 
        _privateMessenger = new Messenger(); 
        SimpleIoc.Default.Register(() => _privateMessenger, "PrivateMessenger");
      } 
      public void Update() 
      { 
       _privateMessenger.Send(new NotificationMessage("DoSomething"));
      } 
} 
public class FirstViewModel 
{ 
     public FirstViewModel()
     { 
        var messenger = SimpleIoc.Default.GetInstance<Messenger>("PrivateMessenger");         messenger.Register<NotificationMessage>( this, message => { 
          // 此消息是要发送给我。 
           }); 
     } 
}

图 8:使用令牌的不同信道

public class MainViewModel 
{ 
       public static readonly Guid Token = Guid.NewGuid(); 
       public void Update() 
       { 
         Messenger.Default.Send(new NotificationMessage("DoSomething"), Token);
       } 
} 
public class FirstViewModel 
{ 
       public FirstViewModel() 
       { 
          Messenger.Default.Register<NotificationMessage>( this, MainViewModel.Token, message => {
           // 此消息是要发送给我。 
            }); 
       } 
}

图 9:使用消息类型来定义上下文

public class Sender
{ 
      public void SendBoolean() 
      { 
          Messenger.Default.Send(true);
      } 
      public void SendNotification()
      { 
         Messenger.Default.Send( new NotificationMessage<bool>(true, Notifications.PlayPause)); 
      } 
} 
public class Receiver 
{
      public Receiver() 
      { 
          Messenger.Default.Register<bool>( this, b => { 
               // 不确定如何处理此布尔。
            }); 
          Messenger.Default.Register<NotificationMessage<bool>>( this, message => {
               if (message.Notification == Notifications.PlayPause) 
               { 
                     // 对消息执行某操作。
                     Content. Debug.WriteLine(message.Notification + ":"+ message.Content); 
               } 
            }); 
       } 
}

图 10:发送 PropertyChangedMessage

public class BankViewModel :ViewModelBase 
{ 
        public const string BalancePropertyName = "Balance"; 
        private double _balance; 
        public double Balance 
        { 
           get { 
                    return _balance; 
               }
           set { 
                    if (Math.Abs(_balance - value) < 0.001) 
                    {
                      return; 
                    }
                   var oldValue = _balance; 
                   _balance = value; 
                   RaisePropertyChanged(BalancePropertyName, oldValue, value, true);
                } 
        } 
} 
public class Receiver 
{
        public Receiver() 
        { 
             Messenger.Default.Register<PropertyChangedMessage<double>>( this, message => { 
             if (message.PropertyName == BankViewModel.BalancePropertyName) 
             { 
               Debug.WriteLine( message.OldValue + " --> " + message.NewValue); 
             } 
          }); 
        } 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值