MVVM Легкое push / pop сообщение для передачи параметров - PullRequest
1 голос
/ 17 марта 2011

Вопрос к Лорану и др.

Я добавил функции расширения в мессенджер 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);
            }
        }
    }
}

1 Ответ

0 голосов
/ 18 марта 2011

У меня есть несколько похожая концепция в моем бэклоге, очень интересная реализация здесь. Я добавлю это в закладки и вернусь к нему, когда придет время.

Приветствия и спасибо, что поделились! Laurent

...