【问题标题】:Implementing a message/subscription mechanism in C#在 C# 中实现消息/订阅机制
【发布时间】:2013-01-01 22:59:22
【问题描述】:

我正在使用 MVVM 模式对 WPF 应用程序进行原型设计。在回答this question 之后,我设置了一个ModelProviderService,它将模型作为属性公开。服务的消费者是视图模型,即他们从服务中提取模型,而不是自己实例化它们。

class ModelProviderService {

  private LoginModel loginModel;
  public LoginModel LoginModel {
    get { return loginModel; }
    set { loginModel = value; }
  }

  private ProjectsModel projectsModel;
  public ProjectsModel ProjectsModel {
    get { return projectsModel; }
    set { projectsModel = value; }
  }

  public ModelProviderService() {
    loginModel = new LoginModel();
    projectsModel = new ProjectsModel();
  }    
}

现在,接下来会发生什么:

  • viewmodel 改变一个属性,例如LoginModel 属性。
  • viewmodel 通过设置其属性将模型属性推回服务:modelService.LoginModel.MyProperty = localLoginModel.MyProperty;
  • 该服务应发布一条消息:“嘿,我的 LoginModel 类型的模型刚刚更改。”
  • 已订阅此消息的任何其他视图模型将从服务中提取此更改的模型。

我该如何实现:

  1. “广播消息”?
  2. 订阅消息?

【问题讨论】:

    标签: c# wpf events mvvm message


    【解决方案1】:

    您可以使用MessageBusEventAggregator 通过弱引用向订阅者发布消息。看看my implementation(或the NuGet packgage)。

    它还可以通过在 Handle 方法上应用 HandleOnUIThreadAttribute 为您将消息处理编组到 UI 线程(如果您需要更新 UI 组件)。

    在您的情况下的用法类似于:

    // The message
    public class LoginModelChanged
    {
        public LoginModelChanged(LoginModel model)
        {
            Model = model;
        }
    
        public LoginModel Model { get; private set; }
    }
    
    // Service that publishes messages
    public class ModelProviderService
    {
        private IMessageBus _messageBus;
        private LoginModel _loginModel;
    
        public ModelProviderService(IMessageBus messageBus)
        {
            _messageBus = messageBus;
        }
    
        public LoginModel LoginModel
        {
            get { return _loginModel; }
            set
            {
                _loginModel = value;
                _messageBus.Publish(new LoginModelChanged(value));
            }
        }
    }
    
    // Subscribing ViewModel
    public class SomeViewModel : IHandle<LoginModelChanged>
    {
        public SomeViewModel(IMessageBus messageBus)
        {
            messageBus.Subscribe(this);
        }
    
        public void Handle(LoginModelChanged message)
        {
            // Do something with message.Model
        }
    }
    

    如果您想了解更多有关内部工作原理以及如何实现的信息;查看GitHub repository 中的源代码。随意使用代码:)

    【讨论】:

      【解决方案2】:

      如果您想在 WPF 应用程序中分发消息,您可以使用 EventAggregatorprism 框架。

      EventAggregator 允许视图模型弱订阅事件,不需要知道发送者。这使您可以轻松地跨组件或模块分发消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-15
        • 1970-01-01
        • 2018-08-14
        • 1970-01-01
        • 2012-01-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多