由模型事件触发的ViewModel中的WPF MVVM PropertyChanged通知

时间:2013-02-11 23:26:19

标签: c# wpf data-binding mvvm mvvm-light

我在理解如何将Model类中的属性更改事件通过ViewModel传播到视图中时遇到问题。我试图遵循MVVM模式,所以请记住这一点。

我有一个模型,我试图通过ViewModel公开。我的Model类查询Api调用以获取服务器状态并在公共属性中公开该状态。例如:

public class ServerStatusRequest : ApiRequest
{
    //Exposable properties by request
    public ServerStatusHelperClass Status { get; set; }

其中ServerStatusHelperClass只是查询中合并结果的包装器:

public class ServerStatusHelperClass
{
    public bool ServerStatus { get; set; }
    public int OnlinePlayers { get; set; }

关于我的ApiRequest基类的一个很酷的事情是,它检查特定Api调用的缓存时间,并使用System.Timers.Timer更新结果。因此,例如,ServerStatus Api调用在Api上缓存3分钟,因此每3分钟我的ServerStatusApiRequest对象将获得新数据。我在所有ApiRequest类中公开UpdatedResults事件,以便在新数据进入时通知。

现在我希望我的ViewModel拥有ServerStatusApiRequest的实例并绑定到其ServerStatusHelperClass Status属性,并在每次更新信息时保持最新的更改,但我的视图(用于绑定)无法了解我的模型,因此,我不知道我的UpdatedResults课程中的ApiRequest事件。如何通过我的ViewModel将其反映到View中?我在做一些完全奇怪的事情吗?

以下是我所做的半工作,但我觉得这是一个非常 hacky 的解决方案:

在我的ViewModel中:

    public const string EveServerStatusPropertyName = "EveServerStatus";
    private ServerStatusRequest _eveServerStatus = new ServerStatusRequest();
    public ServerStatusRequest EveServerStatus
    {
        get
        {
            return _eveServerStatus;
        }
        set
        {
            //if (_eveServerStatus == value)
            //{
            //    return;
            //}

            //RaisePropertyChanging(EveServerStatusPropertyName);
            _eveServerStatus = value;
            RaisePropertyChanged(EveServerStatusPropertyName);
        }
    }

    public void UpdateEveServerStatus(object sender, EventArgs e)
    {
        EveServerStatus = (ServerStatusRequest)sender;
    }

在ViewModels构造函数中,我订阅了Model的事件:

EveServerStatus.UpdatedResults += new UpdatedResultsEventHandler(UpdateEveServerStatus);

如您所见,这似乎非常多余。我还遇到了一个问题,我必须在EveServerStatus的设置器中注释掉该检查,因为此时_eveServerStatus已经更新为value,只是在它不知情的情况下我想要无论如何要解雇这个事件。

我觉得我在这里错过了一个关键概念,可以更容易地将这一切联系在一起。

感谢您的任何意见。

1 个答案:

答案 0 :(得分:1)

我遇到了一种更好的方法来实现我正在寻找的行为。以下是我的ViewModel中的代码:

    private ServerStatusRequest _eveServerStatus = new ServerStatusRequest();

    public ServerStatusRequest EveServerStatus
    {
        get
        {
            return _eveServerStatus;
        }
    }

没有setter,因为我的ViewModel和我的View都应该更改此数据。在我的ServerStatusRequest类中,我有一个公开ServerStatusHelperClass对象的属性,如问题所示。我更改了ServerStatusHelperClass并将其设为INotifyPropertyChanged,因此:

public class ServerStatusHelperClass : ObservableObject
{
    private bool _serverStatus;
    public bool ServerStatus
    {
        get
        {
            return _serverStatus;
        }
        set
        {
            _serverStatus = value;
            RaisePropertyChanged("ServerStatus");
        }
    }
...

ObservableObject只是一个从mvvmlight为我实现INotifyPropertyChanged的简单类。

通过这样做,当我的ApiRequest类修改它的ServerStatusHelperClass对象时,我的视图会自动更新。

欢迎输入此解决方案。