【问题标题】:caliburn.micro eventAggregator: Handling message in Screen Collectioncaliburn.micro eventAggregator:处理屏幕集合中的消息
【发布时间】:2015-08-07 10:35:04
【问题描述】:

我的 caliburn 微应用程序中有以下代码。 我正在使用 eventAggregator 将消息从一个视图模型发送到另一个视图模型。

考虑以下代码:

public class ShellViewModel : Conductor<IWorkspace>.Collection.OneActive, IShell
{
   ...
}

public class ViewModelA
{
   ...
}

public class ViewModelB
{
   ViewModelA messageSender{get;set};
   ...
}

要求: 我需要从 ViewModelA 向 ViewModelB 发送消息。

问题: 有多个 ViewModel 实例被创建并添加到屏幕集合中。我只需要将消息发送到特定的 ViewModelB 实例。 所有其他视图模型实例都应忽略该消息。

注意: 在上面的代码示例中,我从 viewmodel 对象messageSender 向封闭类发送消息。所以消息应该只发送到父对象的实例。

问题

  1. caliburn micro 中是否有可用的内置功能 处理这种情况的框架?
  2. 如果没有,是否有任何技术可以唯一标识视图模型 处理消息的实例?

【问题讨论】:

    标签: c# wpf mvvm caliburn.micro eventaggregator


    【解决方案1】:

    我认为 Caliburn EventAggregator 没有内置此功能。PRISM EventAggregator 允许传入过滤器函数,而 MVVMLight Messenger 使用令牌对象。

    我想在 Caliburn 中,您需要在消息中包含一些内容,以允许订阅者决定他们是否应该处理该消息。

    【讨论】:

      【解决方案2】:

      IHandle&lt;T&gt; 用于需要对消息“执行”的类,您使用 IEventAggregator 发布,通常作为注入。当它处于非活动状态或关闭时,请记住根据激活和停用来订阅和取消订阅。只有继承IHandle&lt;T&gt; 及其“唯一”签名的类才会响应广播。现在当然,如果你有多个 IHandle&lt;string&gt;,那么所有的虚拟机都会尝试处理发送的消息,如果它们被连接起来这样做的话。

      //Handle<T> for any built-in type or something you create like MessageEvent etc.
      public class ViewModelB : Screen, IHandle<string>   
      {
         public ViewModelB(IEventAggregator events){
            _event = events;
            _events.Subscribe(this);
         }
      
         private void Handle(string t){
            MessageBox.Show(t);
         }
      }
      
      public class ViewModelA : Screen
      {
          private readonly IEventAggregator _event;
      
          public ViewModelA(IEventAggregator events)
          {
              _event = events;
              _event.Subscribe(this);
          }
      
          public void SomethingWasClicked()
          {
               _event.PublishOnUIThread("Hello, World!");
           }
      }
      

      【讨论】:

        【解决方案3】:

        要详细说明 mvermef 所说的内容,您需要在将处理特定消息的视图模型中实现 IHandle&lt;T&gt; 接口。由于他为消息类型选择了string,因此如果其他视图模型实现了IHandle&lt;string&gt; 接口,您必须解析ViewModelB 中的消息来处理它。回到您的示例并使其更具体地用于ViewModelB,您可以从处理基于字符串的消息的基类继承。

        public class StringMessageEventBase
        {    
            private string _Message;
            public StringMessageEventBase()
                : this(null) { }
        
            public StringMessageEventBase(string message)
            {
                _Message = message;
            }
        
            public string Message
            {
                get { return _Profile; }
                set { _Profile = value; }
            }
        }
        
        public class ViewModelBMessageEvent : StringMessageEventBase
        {
            public ViewModelBMessageEvent(string message)
                : base(profile) {}
        }
        

        现在如果您在视图模型中实现IHandle&lt;ViewModelBMessageEvent&gt; ViewModelB,那么只有ViewModelB 的实例会处理该消息。

        public class ViewModelB : IHandle<ViewModelBMessageEvent>
        {
            private readonly IEventAggregator _Aggregator;
        
            public ViewModelB(IEventAggregator aggregator)
            {
                if (aggregator == null)
                    throw new ArgumentNullException("aggregator");
                _Aggregator = aggregator;
                _Aggregator.Subscribe(this);
            }
        
            public void Handle(ViewModelBMessageEvent message)
            { 
                // do some thing with your message here
                var msg = message.Message;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多