Caliburn.micro - 在另一个视图模型中通知属性更改的viewmodel

时间:2014-08-13 11:31:50

标签: c# wpf mvvm viewmodel caliburn.micro

我有一个连接到服务器并向其发送命令的程序。 在我的程序中我有2个窗口,其中一个是带有显示当前状态的文本框的工具栏(我们称之为“mainviewmodel”),另一个是登录窗口,它接收用户名和密码并将我登录到服务器(我们称之为“loginviewmodel”)

现在,为了让mainviewmodel知道loginviewmodel,我使用了这个:

[Import]
Private LoginViewModel loginViewModel;

从mainviewmodel午餐登录窗口我有以下功能:

public void Login()
{
    if (!loginViewModel.CanInvokeLogin)
        return;
    if (loginViewModel.IsActive)
    {
        loginViewModel.Focus();
    }
else
    {
        windowManager.ShowWindow(loginViewModel);
    }
}

正如您所看到的 - 我在loginviewmodel中有一个名为CanInvokeLogin的属性,它指示登录是否正在进行中。

on mainviewmodel我有一个属性,显示当前客户端状态(绑定到视图的文本框)

public string TextboxDescription
{
    get
    {
        switch (AvailabilityStatus.Type)
        {
            case AvailabilityStatusType.READY:
                return ("Ready");
            case AvailabilityStatusType.BREAK:
                return (AvailabilityStatus.Reason);
            case AvailabilityStatusType.DISCONNECTED:
                if (!loginViewModel.CanInvokeLogin)
                {
                    return ("Conencting");
                }
                return ("connected");
            default:
                return ("Please wait...");
            }
        }
    }
}

我的问题是 - 除非

,否则状态不会在视图上更新
NotifyOfPropertyChange(() => TextboxDescription);
正在调用

,所以我需要在

时调用它
NotifyOfPropertyChange(() => CanInvokeLogin);
正在调用

,但这发生在另一个视图模型上。

那么,如何通知mainviewmodel caninvokelogin已被更改? 我知道我可以使用eventAggregator并从一个视图模型向另一个视图模型发送消息,但这听起来像用大炮杀死一只苍蝇而我打赌这是一种更简单的方式,

有什么建议吗?

1 个答案:

答案 0 :(得分:3)

处理属性更改事件

PropertyChanged事件只是一个事件,所以没有什么可以阻止你从另一个视图模型中监听该事件,如果这是你需要的。

this.loginViewModel.PropertyChanged += this.OnLoginPropertyChanged;

事件处理程序方法看起来像这样......

private void OnLoginPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "TextboxDescription") {
        // Do something.
    }
}

提升StatusChanged事件:

老实说,如果我自己实现这个,我只会在状态发生变化时从LoginViewModel触发事件,然后再处理这些事件,这似乎是一个更清晰的解决方案。

this.loginViewModel.StatusChanged += this.OnLoginStatusChanged;

private void OnLoginStatusChanged(object sender, LoginStatusChangedEventArgs e)
{
    // Do something.
    switch (e.StatusType)
    {
        ...
    }
}

我会像这样定制事件args ......

public class LoginStatusChangedEventArgs : EventArgs
{
     public AvailabilityStatusType StatusType { get; set; }
}

当状态发生变化时,只需触发此事件,侦听器就可以处理。

事件聚合器:

你也可以使用事件聚合器,但是除非你有许多需要监听的断开连接的类,否则我可能觉得它有点矫枉过正。

this.eventAggregator.Publish(new LoginStatusChangedMessage(AvailabilityStatusType.Disconnected));