WPF绑定控件仅在值更改为null时更新
本文关键字:null 更新 绑定 控件 WPF | 更新日期: 2023-09-27 18:17:13
我绑定了一个控件到动态类型的属性,我的MainWindow类继承自INotifyPropertyChanged,也定义了方法OnPropertyChanged:
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
我的xaml看起来像这样
<ListBox DataContext="{Binding ElementName=UI}" Name="EquipmentKinds" ItemsSource=" {Binding system_slots}" Grid.Row="1" Margin="10, 10, 10, 10" SelectionChanged="EquipmentKinds_SelectionChanged"/>
<TextBox Name="EditEquipmentKinds" Grid.Row="2" Margin="10, 10, 10, 10" Height="25" TextChanged="EditEquipmentKinds_TextChanged" />
system_slots属性声明为
public dynamic system_slots
{
get
{
if (_system != null)
{
return _system.equipment_kinds;
}
else
{
return null;
}
}
set { _system.equipment_kinds = value; OnPropertyChanged("system_slots"); OnPropertyChanged("system"); }
}
每次我改变system_slots的值,我调用OnPropertyChanged方法。
当我例如添加新的槽到system_slots,我需要设置system_slots为空,如果我想要listbox更新,例如,我的代码这是
dynamic new_system = CreateCopyOfSystem(system);
new_system.equipment_kinds.Add("New Slot".ToRubyString());
system_slots = null;
system_slots = new_system.equipment_kinds;
OnPropertyChanged("system");
OnPropertyChanged("system_slots");
如果我没有设置system_slots为null,它不会更新,任何帮助,因为我是新的WPF??
EDIT: What i tried is to use ObservableCollection, DependencyProperties, and I found here an example where someone Get Binding and trigger it manually but still it didn't help.
所有动态类型都是来自IronRuby库的ruby对象(意味着自定义类集合的数组和哈希)。如果我理解WPF控件应该更新,如果绑定到对象,我调用OnPropertyChange(Object_name),但它不更新,直到我改变对象为空。对于observableCollection的错误,它是从RubyArray到observableCollection的转换。
当您使用dynamic
时,很难确切地说出您正在使用的是哪种类型的集合,但似乎有一件事您已经绊倒了。
WPF只会在属性值发生变化时才会注意到为该属性触发的PropertyChanged
事件。对于引用类型,"已更改"意味着"不是ReferenceEquals
到旧值"。您可能已经向列表中添加了一个项目,因此它不再等于它的旧值,但它仍然是ReferenceEquals
到它的旧值-列表本身在内存中的地址与添加项目之前的地址相同。
通过将属性设置为null
并返回到列表,您实际上正在更改属性的值,因为您的集合不是ReferenceEquals
到null
。WPF会注意到这一点,因为值已经改变了。但是,如果列表中有很多项,这会导致WPF做不必要的工作,每次都要重新构建整个列表框。
考虑使用ObservableCollection来代替。每当添加、删除或更改项时,都会触发事件。WPF知道这个类(或者更确切地说是它实现的接口INotifyCollectionChanged),监听它的事件并响应它们。