在C#中实现消息/订阅机制

我正在使用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通过设置其属性将model属性推送回服务:modelService.LoginModel.MyProperty = localLoginModel.MyProperty;
>该服务应发布一条消息:“嘿,我的模型LoginModel刚改变了.”
>订阅此消息的任何其他视图模型都将从服务中提取此更改的模型.

我该如何实现:

>“广播信息”?
>订阅邮件

解决方法

您可以使用MessageBus或EventAggregator通过使用弱引用订阅者发布消息.看看 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中的源代码.随意使用代码:)

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...