5

I want to have Dictionary that would be 'Observable' in order to throw events when its item changing (Remove or Add).

In other class I created such dictionary and set Binding to ListBox.ItemsSourseProperty.
The Binding work well. I can see the items.

But something is wrong: the event PropertyChanged always null.

Can anyone help?

Thanks in advance!

class ObservableDictionary<TKey, TValue> : 
    Dictionary<TKey, TValue>, 
    INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public new void Remove(TKey obj)
    {
        base.Remove(obj);

        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("Remove"));
        }
    }
}
joce
  • 9,624
  • 19
  • 56
  • 74
yossharel
  • 1,819
  • 2
  • 23
  • 29
  • 1
    similar question: http://stackoverflow.com/questions/1098663/general-observable-dictionary-class-for-databinding-wpf-c – Metro Smurf May 18 '10 at 15:02
  • 4
    be cautious when using the new keyword... because that method will only be called when the object is scoped and casted to ObservableDictionary. Since the majority of the framework bindind model will cast it to IEnumerable, Add & Remove will still call the downstream implementation on the base Dictionary. I would instead write your class as a wrapper class that has an internal Dictionary for storage and then implement the IDictionary & INotifyCollectionChanged interfaces and corresponding methods. – Brian Rudolph May 18 '10 at 16:27
  • public class Foo { public void Bar() { Console.WriteLine("Test 1"); } } public class Foo2 : Foo { public new void Bar() { Console.WriteLine("Test 2"); } } var f = new Foo2(); f.Bar(); ((Foo)f).Bar(); Returns Test 2 Test 1 – Brian Rudolph May 18 '10 at 16:32
  • take a look into http://observabledic.codeplex.com/ – Oliver May 20 '10 at 07:51

4 Answers4

5

You should not call PropertyChanged for a collection change event. You need to implement INotifyCollectionChanged.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
3

Did you subscribe the PropertyChanged event?

var dictionary = new ObservableDictionary<int, int>();
dictionary.PropertyChanged += 
    ( sender, args ) => MessageBox.Show( args.PropertyName );
dictionary.Add( 1, 2 );
dictionary.Remove( 1 );

This works for me.

But it would be cleaner to implement the interface IDictionary instead of using the new keyword. Then you can use a private Dictionary instance within your class to safe you the work of implementing everything on your own.

tanascius
  • 53,078
  • 22
  • 114
  • 136
2

Is anyone subscribing to Propertychanged?

For an observable collection, you are going to also want INotifyCollectionChanged

JMarsch
  • 21,484
  • 15
  • 77
  • 125
2

It sounds like you may be looking for a dictionary version of ObservableCollection (see: MSDN), which implements both INotifyCollectionChanged and INotifyPropertyChanged out of the box. Perhaps looking over its implementation in reflector may be helpful? It can be found in the System.Collections.ObjectModel namespace in the System.dll assembly.

Jesse Squire
  • 6,107
  • 1
  • 27
  • 30