用于参数传递的MVVM Light推/弹消息

时间:2011-03-17 15:57:26

标签: mvvm-light

Laurent和其他人的问题。

我已经为MVVM Light messenger添加了扩展功能来推送和弹出消息。我们的想法是,当一个视图模型需要打开另一个视图/视图模型时,它会从消息堆栈中推送参数,然后新打开的视图模型(或者可能是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);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我的积压中有一个类似的概念,这里非常有趣的实现。我会给它添加书签,并在时机成熟时再回过头来。

欢呼并感谢分享! 劳伦