Вопрос к Лорану и др.
Я добавил функции расширения в мессенджер MVVM Light для отправки и извлечения сообщений.Идея состоит в том, что когда viewmodel нужно открыть другой view / viewmodel, он вытолкнет параметры из стека сообщений, а затем вновь открытая viewmodel (или, возможно, viewmodellocator) подпишется на сообщение и вытолкнет сообщение, чтобы получить параметры.Я ищу отзывы об этой идее.Код приведен ниже.
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);
}
}
}
}