Wpf 使用INotifyPropertyChanged而不是DependencyProperties进行数据绑定
一个多星期以来,我一直在努力让数据绑定在WPF中工作。在这里,我确实得到了关于DataContext的宝贵帮助,而且我确实通过DependencyProperties实现了数据绑定。在学习数据绑定的过程中,我遇到了许多关于INotifyPropertyChanged的讨论,以及它在许多方面如何优于DPs。我想我会试一试 我使用的是Josh Smith的基本ViewModel类,我的ViewModel就是从中派生出来的。然而,我在数据绑定工作中遇到了一些问题,我希望这里的人能告诉我哪里出了问题 在我的ViewModel类中,我有一个Wpf 使用INotifyPropertyChanged而不是DependencyProperties进行数据绑定,wpf,mvvm,inotifypropertychanged,dependency-properties,Wpf,Mvvm,Inotifypropertychanged,Dependency Properties,一个多星期以来,我一直在努力让数据绑定在WPF中工作。在这里,我确实得到了关于DataContext的宝贵帮助,而且我确实通过DependencyProperties实现了数据绑定。在学习数据绑定的过程中,我遇到了许多关于INotifyPropertyChanged的讨论,以及它在许多方面如何优于DPs。我想我会试一试 我使用的是Josh Smith的基本ViewModel类,我的ViewModel就是从中派生出来的。然而,我在数据绑定工作中遇到了一些问题,我希望这里的人能告诉我哪里出了问题 在
可观测集合
。在我的GUI中,我有一个绑定到此OC的组合框,即
<ComboBox ItemsSource="{Binding PluginNames}" />
ViewModel的OC名为“PluginNames”:
公共类视图模型
{
public-observeCollection-PluginNames;//将其实例化并添加到其他位置
}
加载GUI时,将调用一个方法来实例化OC并向其添加插件名称。修改OC后,我调用RaisePropertyChanged(“PluginNames”)
。我本来以为,既然WPF数据绑定模型知道INotifyPropertyChanged,这就是我所需要做的一切,它将“神奇地工作”,并用加载的插件更新combobox项。。。但事实并非如此
有人能指出我做错了什么吗?谢谢
更新:我不知道为什么,但是现在它没有做任何明显的更新,而是根本找不到属性。我觉得我真的很愚蠢,在某个地方错过了一个重要的步骤。看起来你暴露了字段而不是属性。绑定仅适用于属性。。。将其更改为:
public class ViewModel
{
public ObservableCollection<string> PluginNames {get; private set;}
}
公共类视图模型
{
公共可观测集合PluginNames{get;private set;}
}
使用INotifyPropertyChanged时,有两件事:
private ObservableCollection<string> pluginNames;
public ObservableCollection<string> PluginNames
{
get { return pluginNames; }
set {
this.pluginNames = value;
RaisePropertyChanged("PluginNames"); // This should raise the PropertyChanged event - use whatever your VM class does for this
}
}
private observeCollection pluginNames;
公共可观测收集插件名称
{
获取{return pluginNames;}
设置{
this.pluginNames=值;
RaisePropertyChanged(“PluginNames”);//这将引发PropertyChanged事件-使用VM类为此所做的任何操作
}
}
这应该会导致所有内容都重新填充。事实上,可能没有理由在属性上设置setter,因为它是一个集合(而且是一个可观察的集合)。是的-但他故意提到他在运行时设置了这个,所以我将其包括在内。里德,我喜欢你展示的方式。。。我绝对应该公开setter,并在那里更改call-raiseproperty,就像我今天看到的所有其他示例一样。太好了@D.Matsumoto:这是在使用INotifyPropertyChanged时处理属性的标准方法。根据您使用的ViewModel基类,确切的语法可能会有一些变化(RaisePropertyChanged可以通过不同的方式完成),但您需要遵循这种常规模式。此外,如果新值与原始值不同,则通常只提升更改的属性…太棒了,听起来不错。一旦我熟悉了这一点,我将尝试采用“无字符串”的方式来处理属性名称——我认为如果符号不匹配,人们会使用表达式树来获取编译器错误。不要使用自动属性——它们不会引发PropertyChanged事件。绝对正确。啊!我最终会在这方面做得更好。:)在这里接受最古老的正确答案是正确的吗?我想是的。您可以为
可观察集合使用自动属性。setter可能应该是私有的。sixtlettervariables:如果您从未实例化新集合,这是正确的,但是在这种情况下,您应该使用只读
字段和只读属性。
public class ViewModel
{
public ObservableCollection<string> PluginNames {get; private set;}
}
private ObservableCollection<string> pluginNames;
public ObservableCollection<string> PluginNames
{
get { return pluginNames; }
set {
this.pluginNames = value;
RaisePropertyChanged("PluginNames"); // This should raise the PropertyChanged event - use whatever your VM class does for this
}
}