模型没有实现INotifyPropertyChanged

3

在MVVM模式下,当Models不实现INotifyPropertyChanged接口时,该如何构建ViewModel结构?

我喜欢保持我的Models尽可能简单,仅为了绑定目的实现INotifyPropertyChanged接口似乎是不必要的复杂性。这就是为什么大多数时候我需要我的VMs像以下示例一样包装模型属性:

class ViewModel : INotifyPropertyChanged
{
    private Model model;

    public int MyProperty
    {
        get { return model.MyProperty; }
        set
        {
            if (value != model.MyProperty)
            {
                model.MyProperty = value;

                // Trigger the PropertyChanged event
                OnPropertyChanged("MyProperty");
            }
        }
    }

    /* ... */
}

这将使绑定正常工作,包括双向绑定。

现在,如果一个命令执行具有复杂逻辑的模型方法(影响不同对象的许多属性的值),会发生什么情况?该模型没有实现INotifyPropertyChanged,因此我们无法知道它已更新。唯一我想到的解决方案是使用消息传递(中介者模式)通知所有VM执行该方法,以便每个VM为每个可能受影响的属性触发PropertyChanged事件:

// Sample ICommand.Execute() implementation
public void Execute(object parameter)
{
    var model = (Model)parameter;

    model.VeryComplexMethod();

    // Just an example, the string "VeryComplexMethodExecuted" is
    // sent to all listening VMs. Those VMs will in turn fire the
    // PropertyChanged event for each property that may have changed
    // due to the execution of the complex model method.
    Messaging.Broadcast("VeryComplexMethodExecuted");
}

请分享您的想法,谢谢。

1
@Sheridan,您的意思是模型只是数据吗?逻辑放在哪里?在命令本身中(或者在VM方法中,这是一样的)?如果应用程序是一个象棋游戏呢?AI不是模型的一部分吗? - dan
1
一般而言:我把我的模型看作是数据和业务逻辑。我的虚拟机存在的目的是以一种有意义的方式向视图(xaml)公开模型。虚拟机还将提供命令,以便视图上的输入事件可以触发某些逻辑(任何类型的逻辑)。 - dan
1
我不喜欢模型知道会有人绑定它。 - dan
2
@sheridan,“模型中没有逻辑”这个概念绝对不是MVVM。是“没有显示逻辑”,但不是“没有逻辑”。模型不总是只有数据。在这种情况下,我将关注我的模型如何发出“准备就绪”的信号,假设某些操作需要时间(例如计算移动)。此消息不会与UI实现绑定,但应该是VM需要担心的事情,以便它可以确保其对模型的了解是准确和最新的。 - Mashton
1
@Mashton 我同意。ViewModel 包含显示逻辑并与模型交互。它不应包含业务规则(在我看来)。 - dan
显示剩余24条评论
1个回答

0

将您的成员声明为虚拟的,并使用类似于Castle Dynamic Proxy的工具自动注入更改通知:

http://ayende.com/blog/4106/nhibernate-inotifypropertychanged

当在数据层中创建模型时,必须小心使用此方法,因为它将返回一个全新的实例。您的数据库代码会认为对象已更改并再次进行序列化,这将对性能产生巨大影响。幸运的是,所有优秀的ORM都提供了机制,让您在创建时替换类包装器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接