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

发布于 2024-08-16 11:07:40 字数 1164 浏览 4 评论 0原文

一个多星期以来,我一直在努力让数据绑定在 WPF 中工作。我确实在这里获得了有关 DataContext 的宝贵帮助,并且我确实通过 DependencyProperties 获得了数据绑定。当我学习数据绑定时,我遇到了许多关于 INotifyPropertyChanged 的​​讨论以及它如何在许多方面比 DP 更好。我想我应该尝试一下。

我正在使用 Josh Smith 的基本 ViewModel 类,我的 ViewModel 是从它派生的。但是,我在使数据绑定正常工作时遇到了一些麻烦,希望这里有人能告诉我哪里出了问题。

在我的 ViewModel 类中,我有一个 ObservableCollection。在我的 GUI 中,我有一个绑定到此 OC 的组合框,即

<ComboBox ItemsSource="{Binding PluginNames}" />

GUI 的 DataContext 设置为 ViewModel,

private ViewModel _vm;

public GUI()
{
  InitializeComponent();
  _vm = new ViewModel();
  this.DataContext = _vm;
}

即 ViewModel 具有名为“PluginNames”的 OC:

public class ViewModel
{
  public ObservableCollection<string> PluginNames;  // this gets instantiated and added to elsewhere
}

加载 GUI 时,会调用一个方法来实例化OC 并向其中添加插件名称。修改 OC 后,我调用 RaisePropertyChanged( "PluginNames")。我原以为,由于 WPF 数据绑定模型可以识别 INotifyPropertyChanged,所以这就是我需要做的所有事情,并且它将“神奇地工作”并使用加载的插件更新组合框项目......但事实并非如此。

有人可以指出我在这里做错了什么吗?谢谢!

更新:我不知道为什么,但现在它不是不做任何明显的更新,而是根本找不到该属性。我觉得我真的很愚蠢,在某个地方错过了重要的一步。

I have been wrestling with getting databinding to work in WPF for a little over a week. I did get valuable help here regarding the DataContext, and I did get databinding to work via DependencyProperties. While I was learning about databinding, I came across numerous discussions about INotifyPropertyChanged and how it is better than DPs in many ways. I figured that I would give it a shot and try it out.

I am using Josh Smith's base ViewModel class and my ViewModel is derived from it. However, I'm having a bit of trouble getting databinding to work, and am hoping that someone here can tell me where I'm going wrong.

In my ViewModel class, I have an ObservableCollection<string>. In my GUI, I have a combobox that is bound to this OC, i.e.

<ComboBox ItemsSource="{Binding PluginNames}" />

The GUI's DataContext is set to the ViewModel, i.e.

private ViewModel _vm;

public GUI()
{
  InitializeComponent();
  _vm = new ViewModel();
  this.DataContext = _vm;
}

and the ViewModel has the OC named "PluginNames":

public class ViewModel
{
  public ObservableCollection<string> PluginNames;  // this gets instantiated and added to elsewhere
}

When the GUI is loaded, a method is called that instantiates the OC and adds the plugin names to it. After the OC is modified, I call RaisePropertyChanged( "PluginNames"). I was expecting that since the WPF databinding model is cognizant of INotifyPropertyChanged, that this is all I needed to do and it would "magically work" and update the combobox items with the plugins that got loaded... but it doesn't.

Can someone please point out what I've done wrong here? Thanks!

UPDATE: I'm not sure why, but now instead of not doing any apparent updating, it's not finding the property at all. I think I'm being really stupid and missing an important step somewhere.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原谅过去的我 2024-08-23 11:07:40

当您使用 INotifyPropertyChanged 时,有两件事:

  1. 您需要使用属性,而不是字段
  2. 当您设置属性时,您应该始终引发属性更改事件。

您需要重新设计它,使其看起来更像:

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
    }
}

这应该会导致所有内容重新填充。

When you're working with INotifyPropertyChanged, there are two things:

  1. You'll need to use properties, not fields
  2. You should always raise the property changed event when you set hte properties.

You'll want to rework this so it looks more like:

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
    }
}

That should cause everything to repopulate.

乖不如嘢 2024-08-23 11:07:40

看起来你暴露的是领域而不是财产。绑定仅适用于属性...将其更改为:

public class ViewModel
{
  public ObservableCollection<string> PluginNames {get; private set;} 
}

It looks like you've exposed field not property. Bindings works for properties only... Change it to:

public class ViewModel
{
  public ObservableCollection<string> PluginNames {get; private set;} 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文