我将控件绑定到动态类型的属性,My 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设置为null如果我想要更新列表框,例如我的代码是
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控件应该更新如果绑定到Object并且我调用OnPropertyChange(Object_name),但它不会更新,直到我将Object更改为null。 Ass对于observableCollection的错误,它是从RubyArray到ObservableCollection的Coversion。
答案 0 :(得分:3)
当你使用dynamic
时,很难确切地说出你正在使用什么类型的收藏,但似乎有一件事你已经绊倒了。
如果属性值已更改,WPF将仅注意为属性触发的PropertyChanged
事件。对于参考类型,“已更改”表示“不是ReferenceEquals
到旧值”。您可能已将一个项目附加到列表中,因此它不再等于其旧值,但它仍然是ReferenceEquals
到其旧值 - 列表本身在内存中的地址与之前的地址相同项目已添加到其中。
通过将属性设置为null
并返回列表,您实际上正在更改属性的值,因为您的集合不是ReferenceEquals
到null
。 WPF注意到这一点,因为值已经改变。但是,如果列表中有很多项,这会导致WPF执行不必要的工作,每次都重建整个列表框。
请改用ObservableCollection。每当添加,删除或更改项目时,都会触发事件。 WPF知道这个类(或者更确切地说是它实现的接口INotifyCollectionChanged),监听它的事件并响应它们。