2011-03-17 19 views
1

Laurent和其他人的问题。用于参数传递的MVVM轻推/弹出消息

我已经为MVVM Light messenger添加了扩展函数来推送和弹出消息。这个想法是,当视图模型需要打开另一个视图/视图模型时,它会从消息堆栈中推入参数,然后新打开的视图模型(或可能是视图模式)将订阅消息并弹出消息以获取参数。我正在寻找关于这个想法的反馈。该代码发布如下。

MVVMlightMessengerStackExtension.cs(下面的代码已经从原来的职位更新清理了一点东西,并与堆栈行为更加一致)

namespace GalaSoft.MvvmLight.Messaging 
{ 
    public static class MessageHelper 
    { 
     /// <summary> 
     /// Store a list of all the pushed messages 
     /// </summary> 
     private static List<Tuple<int, object, object>> _q = new List<Tuple<int, object, object>>(); 
     private static int _q_idx = Int32.MaxValue; // SL has no SortedList or SortedDictionary so keep an index the of the list to push/pops are in order 

     /// <summary> 
     /// Push a message for later retrival. Typically by a viewmodel constructor. 
     /// </summary> 
     /// <typeparam name="TMessage"></typeparam> 
     /// <param name="M"></param> 
     /// <param name="message"></param> 
     /// <param name="token"></param> 
     [DebuggerStepThrough()] 
     public static void Push<TMessage>(this Messenger M, TMessage message, object token = null) 
     { 
      Monitor.Enter(_q); 
      try 
      { 
       _q.Add(Tuple.Create<int, object, object>(_q_idx--, message, token)); 
      } 
      finally 
      { 
       Monitor.Exit(_q); 
      } 
     } 

     /// <summary> 
     /// Send a stored/delayed message 
     /// </summary> 
     /// <typeparam name="TMessage"></typeparam> 
     /// <param name="M"></param> 
     [DebuggerStepThrough()] 
     public static void PopAndSend<TMessage>(this Messenger M, object token = null) 
     { 
      TMessage mesg = M.Pop<TMessage>(token); 
      if (token != null) 
       M.Send(mesg, token); 
      else 
       M.Send(mesg); 
     } 

     /// <summary> 
     /// Pop a stored/delayed message 
     /// </summary> 
     /// <typeparam name="TMessage"></typeparam> 
     /// <param name="M"></param> 
     [DebuggerStepThrough()] 
     public static TMessage Pop<TMessage>(this Messenger M, object token = null) 
     { 
      Monitor.Enter(_q); 
      try 
      { 
       var result = _q.OrderBy(a => a.Item1).FirstOrDefault(a => a.Item2 is TMessage && a.Item3 == token); 
       if (result == null) 
        throw new InvalidOperationException("The stack is empty."); 
       _q.Remove(result); 
       return (TMessage)result.Item2; 
      } 
      finally 
      { 
       Monitor.Exit(_q); 
      } 
     } 

     /// <summary> 
     /// Peek at a stored/delayed message 
     /// </summary> 
     /// <typeparam name="TMessage"></typeparam> 
     /// <param name="M"></param> 
     [DebuggerStepThrough()] 
     public static TMessage Peek<TMessage>(this Messenger M, object token = null) 
     { 
      Monitor.Enter(_q); 
      try 
      { 
       var result = _q.OrderBy(a => a.Item1).FirstOrDefault(a => a.Item2 is TMessage && a.Item3 == token); 
       if (result == null) 
        throw new InvalidOperationException("The stack is empty."); 
       return (TMessage)result.Item2; 
      } 
      finally 
      { 
       Monitor.Exit(_q); 
      } 
     } 

     /// <summary> 
     /// Clear the stack 
     /// </summary> 
     /// <typeparam name="TMessage"></typeparam> 
     /// <param name="M"></param> 
     [DebuggerStepThrough()] 
     public static void Clear(this Messenger M) 
     { 
      Monitor.Enter(_q); 
      try 
      { 
       _q.Clear(); 
      } 
      finally 
      { 
       Monitor.Exit(_q); 
      } 
     } 

     /// <summary> 
     /// Clear the stack 
     /// </summary> 
     /// <typeparam name="TMessage"></typeparam> 
     /// <param name="M"></param> 
     [DebuggerStepThrough()] 
     public static void Clear<TMessage>(this Messenger M) 
     { 
      Monitor.Enter(_q); 
      try 
      { 
       var delList = _q.Where(a => a.Item2 is TMessage); 
       foreach (var item in delList) 
        _q.Remove(item); 
      } 
      finally 
      { 
       Monitor.Exit(_q); 
      } 
     } 
    } 
} 

回答

0

我有我的积压有点类似的概念,非常有趣在这里执行。我会将其加入书签,并在时间到来时再回来。

欢呼和感谢分享! Laurent