使用MVVM模式时,与属性更改相关的代码是应该放入setter还是事件?

时间:2010-09-16 02:57:34

标签: c# mvvm setter

寻找有关放置代码的位置的指导,这取决于对属性的更改。

例如,我有一个视图模型,用于保存应用程序设置的状态

public SettingsViewModel(ISettingsRepository settings)
{
    _settings = settings;
    // ...
}

对于设置属性的每次更改,我们必须将此更改保留到存储库,并且在某些属性上,其他属性会受到影响,因此需要其他代码。

我开始只是将这个逻辑添加到setter

public ProjectCollection Projects
{
    get { return _projects; }
    set
    {
        if (_projects == value) return;
        _projects = value;
        RaisePropertyChanged("Projects");

        // Extra work needed when collection of projects change
        _settings.SaveProjects(_projects);
        Startable = _projects != null && _projects.Count > 0;
    }
}

然后交换为PropertyChanged的{​​{1}}事件连接,并从属性设置器中删除了其他代码

INotifyPropertyChanged

将逻辑设置在setter中意味着编写更少的代码,错误地将错误的属性名称连接起来的可能性更小(单元测试应该选择这个)并且会稍快一点,尽管可能是微不足道的。

将逻辑连接到事件似乎是一种更易于维护的方法,只要方法被恰当地命名,它应该更容易遵循代码,并且意味着除了设置属性之外,setter不做其他工作。我猜它也可以提供更多的灵活性,使用上面的例子,如果要求发生变化,以便持续发生变化,例如另一个事件,单击“保存”按钮而不是属性更改,然后代码应该更容易更改。

我很欣赏这是一个主观问题,但我是MVVM模式的新手(尽管我认为它可能适用于任何setter逻辑?)所以我在寻求其他方法之前寻找其他原因。谢谢!

1 个答案:

答案 0 :(得分:4)

在决定放置哪些代码时,请记住:一个ViewModel用于将数据呈现给View 。它可以稍微按摩或操纵数据(当然 - 在一定程度上改变一个颜色可以被认为是非常好的)。 ViewModel对UI没有任何了解,也不知道有关保存数据的任何信息。

属性设置器应该尽可能简单,如果有任何依赖它们的话,它们应该通知(主要是这种情况 - VM用于绑定)。这意味着使用OnPropertyChanged()事件处理程序的第二个示例比第一个示例更好。

然而,它仍然知道我喜欢的。我会提出模型可以订阅的事件,让模型完成工作。 ViewModel应该只是说“嘿,我的数据已经改变了,我不关心你对它做了什么,但我已经告诉过你这样做你喜欢什么”。然后,模型可以立即保存,或者在持久化数据之前进行更多更改。

相关问题