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

时间:2014-08-10 04:16:29

标签: c# wpf xaml ironruby

我将控件绑定到动态类型的属性,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。

1 个答案:

答案 0 :(得分:3)

当你使用dynamic时,很难确切地说出你正在使用什么类型的收藏,但似乎有一件事你已经绊倒了。

如果属性值已更改,WPF将仅注意为属性触发的PropertyChanged事件。对于参考类型,“已更改”表示“不是ReferenceEquals到旧值”。您可能已将一个项目附加到列表中,因此它不再等于其旧值,但它仍然是ReferenceEquals到其旧值 - 列表本身在内存中的地址与之前的地址相同项目已添加到其中。

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

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