[英]WPF - data binding - no updates even with INotifyPropertyChanged
[英]INotifyPropertyChanged not working with WPF data binding
我的MainWindow.xaml文件中有一个组合框,如下所示:
<ComboBox Name="material1ComboBox"
HorizontalAlignment="Center"
MinWidth="100"
ItemsSource="{Binding ViewProperties.MaterialDropDownValues}"
SelectedValue="{Binding ViewProperties.Material1SelectedValue}"
SelectionChanged="Material1ComboBoxSelectionChanged">
</ComboBox>
我使用this.datacontext = this
在codebehind中分配了datacontext。
我创建了一个ViewProperties
,它作为MainWindow
的属性进行访问,是一个实现INotifyPropertyChanged并包含MaterialDropDownValues
作为属性的类。
我甚至将MaterialDropDownValues
更改为ObservableCollection
。
问题是数据绑定在初始化时起作用,但是如果更改了MaterialDropDownValues
属性,则不会更新组合框值。
我在ViewProperties
类中有以下内容:
public ObservableCollection<string> MaterialDropDownValues
{
get { return this.materialDropDownValues; }
set
{
this.materialDropDownValues = value;
OnPropertyChanged("MaterialDropDownValues");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
任何想法为什么这不起作用? 我能找到的所有其他答案都建议实现INotifyPropertyChanged并使该属性成为一个observablecollection。
解决方案1:
不要重新创建this.materialDropDownValues
尝试做
this.materialDropDownValues.Clear();
foreach(var mystring in myStrings)
this.materialDropDownValues.Add(mystring);
对于所有新项目。 如果这不起作用,那么尝试解决方案2 ......
解决方案2:
根据我的经验,我认为如果未指定ItemsControl.ItemTemplate
则不会在Property Change通知上刷新像int
, string
, bool
, double
等原始类型的ObservableCollection
。
<ComboBox Name="material1ComboBox"
HorizontalAlignment="Center"
MinWidth="100"
ItemsSource="{Binding ViewProperties.MaterialDropDownValues}"
SelectedValue="{Binding ViewProperties.Material1SelectedValue}"
SelectionChanged="Material1ComboBoxSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type System:String}">
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
这是因为itemscontrol的items容器只需复制item.ToString()就可以在其中为原始数据创建不可观察的项容器。 在上面的代码中, {Binding}
应该在更改整个项目源时更新数据更改。
让我知道这个是否奏效。
当我碰到这样的事情时,我做的第一件事就是玩弄绑定模式。 就像是:
ItemsSource="{Binding Path=ViewProperties.MaterialDropDownValues, Mode=TwoWay}"
这有时会让你失望。 我要确定的另一件事是,如果您在初始加载后实例化新的ViewProperties对象,则通知更改。 如果不这样做,XAML将引用该对象的过时版本,而您的代码隐藏/视图模型在另一个版本上运行。
编辑以回应评论
以下都没有解决问题,但留作参考。
原始答案
问题是您没有为视图指定DataContext
,这是WPF默认查找Binding
值的地方。
如果MainWindow
上的ViewProperties
属性是公共的,您只需将绑定更改为:
ItemsSource="{Binding ViewProperties.MaterialDropDownValues,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}"
这会导致WPF在可视树中的组合框上方找到的Window
的第一个出现时查找属性值。
或者,您可以将Window.DataContext
属性设置为Window.DataContext
实例, ViewProperties
绑定更改为以下内容:
ItemsSource="{Binding MaterialDropDownValues}"
这些中的任何一个都可以工作,但我建议使用后者,因为它更接近MVF模式,这在WPF / XAML应用程序中通常是首选的。
如果你改变你的xaml会发生什么
<ComboBox Name="material1ComboBox"
HorizontalAlignment="Center"
MinWidth="100"
DataContext="{Binding ViewProperties}"
ItemsSource="{Binding MaterialDropDownValues}"
SelectedValue="{Binding Material1SelectedValue}"
SelectionChanged="Material1ComboBoxSelectionChanged">
</ComboBox>
尽管如此,您只需要实例化您的集合一次,并在使用OberservableCollection时使用remove,add和clear。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.