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);
}
}
}
}