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的转换。

WPF绑定控件仅在值更改为null时更新

当您使用dynamic时,很难确切地说出您正在使用的是哪种类型的集合,但似乎有一件事您已经绊倒了。

WPF只会在属性值发生变化时才会注意到为该属性触发的PropertyChanged事件。对于引用类型,"已更改"意味着"不是ReferenceEquals到旧值"。您可能已经向列表中添加了一个项目,因此它不再等于它的旧值,但它仍然是ReferenceEquals到它的旧值-列表本身在内存中的地址与添加项目之前的地址相同。

通过将属性设置为null并返回到列表,您实际上正在更改属性的值,因为您的集合不是ReferenceEqualsnull。WPF会注意到这一点,因为值已经改变了。但是,如果列表中有很多项,这会导致WPF做不必要的工作,每次都要重新构建整个列表框。

考虑使用ObservableCollection来代替。每当添加、删除或更改项时,都会触发事件。WPF知道这个类(或者更确切地说是它实现的接口INotifyCollectionChanged),监听它的事件并响应它们。