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