【发布时间】:2018-06-18 11:42:00
【问题描述】:
假设我有一个名为 MyViewModel 的视图模型,它的实现方式如下:
public class MyViewModel : BindableBase
{
// BindableBase implements INotifyPropertyChanged
// through the method SetProperty() which works fine.
private string _viewModelProperty
public string ViewModelProperty
{
get { return _viewModelProperty; }
set { SetProperty(ref _viewModelProperty, value); }
}
private NestedObjectModel _nestedObject;
public NestedObjectModel NestedObject
{
get { return _nestedObject; }
set { SetProperty(ref _nestedObject, value); }
}
}
如您所见,它包含两个属性。一个字符串和一个对象(不涉及字符串是否也是对象的语义)。对象(或模型)也有一些属性,但这些不是直接用INotifyPropertyChanged 作为视图模型实现的。它可能看起来像这样:
public class NestedObjectModel
{
public string Text { get; set; }
public double Number { get; set; }
}
我想做的是在视图模型中使用INotifyPropertyChanged,以通知模型何时更改(即,如果Text 或Number 被视图模型中的方法更改)。它可能看起来像这样:
// This method is located in the view model
public void ChangeTextInNestedObject(string newText)
{
NestedObject.Text = newText;
OnPropertyChanged(nameof(NestedObject));
}
问题是,我无法让它工作。该值已更改,但 XAML 未达到更改。我还尝试添加属性特定通知:
OnPropertyChanged(nameof(NestedObject.Text));
不能这样吗?我真的必须在模型级别实现INotifyPropertyChanged 吗?
【问题讨论】:
-
如果模型属性直接在 XAML 中绑定,那么是的,您应该实现
INotifyPropertyChanged。另一种绑定方式(不实现INotifyPropertyChanged)是 --- 在 ViewModel 中有一个包装器属性,它是对象实际属性的包装器。 -
感谢@user1672994。我直接绑定到 XAML 中的属性(例如
NestedObject.Text),并且我不希望使用包装器,因为它会使视图模型变得一团糟。我只是希望可以对整个NestedObject进行一般性通知,因此不必在模型级别实现INotifyPropertyChanged。 -
我认为模型可以使用 INotifyPropertyChanged
-
您可以通过
NestedObject = new NestedObjectModel { Text = newText, Number = NestedObject != null ? NestedObject.Number : 0d };之类的方式避免在模型中实现 INotifyPropertyChanged 的必要性。但是,模型类中的 INotifyPropertyChanged 没有任何问题。 -
您是否尝试过在您的
ChangeTextInNestedObject()方法中创建一个新的NestedObject实例,而不仅仅是更新现有的? (IIRC 那么 WPF 倾向于通过引用缓存对象,只有在实际对象实例/引用发生变化时才更新后续/依赖绑定)
标签: c# wpf mvvm inotifypropertychanged