WPF binded controlls only update when value changed to null

1.4k Views Asked by At

i binded a control to property of the dynamic type, My MainWindow Class inherits from INotifyPropertyChanged, Also defined method OnPropertyChanged:

public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(String name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

my xaml looks like that

<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" />

the property system_slots is declared as

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"); }
    }

Every time i changed system_slots value i called OnPropertyChanged method.

When i e.g. add new slot to system_slots i need to set system_slots to null if i want listbox to update e.g. my code for this is

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");

If i didn't set system_slots to null it doesn't update, any help since i'm new to 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.

All dynamic types are ruby objects from IronRuby library (means arrays and hashes for collections of custom made classes). If i understand WPF the control should update if is bound to Object and i call OnPropertyChange(Object_name), but it doesn't update until i change Object to null. Ass For error with observableCollection it was something with Coversion from RubyArray to ObservableCollection.

1

There are 1 best solutions below

10
Luke Woodward On

As you are using dynamic it's difficult to tell exactly what types of collection you are using, but there does seem to be one thing you've tripped over.

WPF will only take notice of a PropertyChanged event fired for a property if the value of the property has changed. For reference types, 'changed' means 'not ReferenceEquals to the old value'. You may have appended an item to the list, so it is no longer equal to its old value, but it will still be ReferenceEquals to its old value - the list itself has the same address in memory as it did before the item was added to it.

By setting the property to null and back to the list, you are actually changing the value of the property, as your collection is not ReferenceEquals to null. WPF takes notice of this because the value has changed. However, if you have a lot of items in the list, this is causing WPF to do unnecessary work, rebuilding the entire listbox every time.

Look at using an ObservableCollection instead. This fires events whenever an item is added, removed or changed. WPF knows about this class (or rather the interface INotifyCollectionChanged that it implements), listens to its events and responds to them.