Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 使用INotifyPropertyChanged而不是DependencyProperties进行数据绑定_Wpf_Mvvm_Inotifypropertychanged_Dependency Properties - Fatal编程技术网

Wpf 使用INotifyPropertyChanged而不是DependencyProperties进行数据绑定

Wpf 使用INotifyPropertyChanged而不是DependencyProperties进行数据绑定,wpf,mvvm,inotifypropertychanged,dependency-properties,Wpf,Mvvm,Inotifypropertychanged,Dependency Properties,一个多星期以来,我一直在努力让数据绑定在WPF中工作。在这里,我确实得到了关于DataContext的宝贵帮助,而且我确实通过DependencyProperties实现了数据绑定。在学习数据绑定的过程中,我遇到了许多关于INotifyPropertyChanged的讨论,以及它在许多方面如何优于DPs。我想我会试一试 我使用的是Josh Smith的基本ViewModel类,我的ViewModel就是从中派生出来的。然而,我在数据绑定工作中遇到了一些问题,我希望这里的人能告诉我哪里出了问题 在

一个多星期以来,我一直在努力让数据绑定在WPF中工作。在这里,我确实得到了关于DataContext的宝贵帮助,而且我确实通过DependencyProperties实现了数据绑定。在学习数据绑定的过程中,我遇到了许多关于INotifyPropertyChanged的讨论,以及它在许多方面如何优于DPs。我想我会试一试

我使用的是Josh Smith的基本ViewModel类,我的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
        }
    }