有没有办法在绑定到Model时引发PropertyChanged?

时间:2014-06-04 14:55:53

标签: wpf mvvm

在我们的WPF / MVVM应用程序中,我们直接绑定到Model的属性,因为Model来自遗留库(我们将INotifyPropertyChanged的支持添加到{{1} })。即,Model的代码看起来像

ViewModel

然后绑定看起来像这样:

Public Class MyViewModel
    Inherits ViewModelBase

    Public Property Model As MyModel

End Class

Everyting工作正常,直到我要求<TextBox Text="{Binding Model.Prop1}" /> 中依赖ViewModel的某些属性。具体来说,我将一个Model.Prop1的{​​{1}}绑定到ItemSource中的集合属性,并且每当ComboBox更改时,都应刷新/重新计算此集合。代码如下所示:

ViewModel

我有一些选择,但我认为它们并不好:

  1. 我可以让Model.Prop1班级持有<ComboBox ItemsSource="{Binding MyCollection}" /> 的引用。在Model的Prop1的setter中,我更新了ViewModel的MyColleciton属性。当然这不是一个好主意
  2. 使用Model进行ViewModelEventAggregator之间的通信。在我看来效率不高,我也需要在Model课程中做出重大改变。
  3. ViewModel拥有一个属性Model并绑定到此属性。在它的getter中返回Model.Prop1并在setter中分配ViewModel。这是我当前的解决方案,但有一个问题:在我们的Prop1中,我们有其他属性/属性是有用的,我们根据此属性/属性创建一个公共ModelProp1 = Value。例如,当Model.Prop1发生更改时,Model类中另一个名为Style的属性设置为IsDirty,而Model中的属性会更改颜色。但是,如果我们使用True中的Prop1而不是View,我们会像其他属性一样失去这种常见的ViewModel行为。
  4. 所以现在我仍然希望使用绑定到Model(不在Style中创建包装器属性),但在更改时以某种方式通知{Binding Model.Prop1}中的其他属性。我能这样做吗?

2 个答案:

答案 0 :(得分:1)

首先,我不喜欢Navigation Property喜欢Model.Prop1,因为你最终会遇到像这样的简单问题。

您需要做的是创建一个ViewModel,只需要在UI中显示并从那里包装Model的属性。

  1. 我不喜欢这个主意。请注意,Model这里并不意味着它是Database中的实际实体。在我看来,ViewModel引用了Model,它具有需要在UI中显示的属性。

  2. 您甚至不需要聚合器或消息服务来更新它。刷新问题应该在ViewModel中处理,而不是Model,我强烈不同意model应该听取事件

  3. 我去了这个,但就像我在开始时说的那样,只需在UI中包含您需要的内容,包括其他有用的属性,即Model.Prop1时然后在ViewModel.Prop1的设置器中进行了更改,更新了IsDirty

  4. 中的Model

答案 1 :(得分:1)

你说我们将INotifyPropertyChanged的支持添加到Model类。现在,如果这意味着您已扩展或添加到原始类并从每个属性添加了对INotifyPropertyChanged.PropertyChanged事件的调用,那么您可以轻松找出使用该事件更改了哪个属性:

Model.PropertyChanged += Model_PropertyChanged;

然后在PropertyChanged处理程序中:

private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Prop1") 
    {
        // The Prop1 property value has changed
        RefreshYourCollection();
    }
}

但是,如果通过我们将INotifyPropertyChanged的支持添加到Model类,则表示您的视图模型实现了INotifyPropertyChanged接口,那么实际上, not INotifyPropertyChanged接口的支持添加到您的Model课程,但您无法执行此操作。

如果是这种情况,那么您首先需要为类中的每个相关属性正确实现INotifyPropertyChanged接口。如果您无法更改原始类,则应将其扩展到正确实现INotifyPropertyChanged接口的类中,并将原始类的每个属性公开为正确通知INotifyPropertyChanged接口的新属性。