2011-03-17 23 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