views:

688

answers:

1

Hello all,

I have a hierarchy of objects that all implement INotifyPropertyChanged. I also have a custom list that derives from BindingList.

It is my understanding that when I add an object that impelements INotifyPropertyChanged to the list, that somehow the PropertyChanged event is automagically wired-up / converted to the ListChanged event.

However, after I set my list as the datasource of my DataGridView, when I change a value in the grid, the ListChanged event does not fire... When I step into the code, it turns out that the PropertyChanged() event is not triggering becaue it is null, which I assume to mean that it is not getting wired-up / converted to the BindingList's ListChanged event, like its supposed to...

For example:

public class Foo : INotifyPropertyChanged
{
     //Properties...
     private string _bar = string.Empty;
     public string Bar
     {
         get { return this._bar; }
         set
         {
              if (this._bar != value)
              {
                  this._bar = value;
                  this.NotifyPropertyChanged("Bar");
              }
         }
     }

     //Constructor(s)...
     public Foo(object seed)
     {
         this._bar = (string)object;
     }

     //PropertyChanged event handling...
     public event PropertyChangedEventHandler PropertyChanged;
     protected void NotifyPropertyChanged(String info)
     {
         if (this.PropertyChanged != null)
         {
             this.PropertyChanged(this, new PropertyChangedEventArgs(info));
         }
     }
}

And here is my custom list class...

public class FooBarList : BindingList<Foo>
{
     public FooBarList(object[] seed)
     {
          for (int i = 0; i < seed.Length; i++)
          {
             this.Items.Add(new Foo(this._seed[i]));
          }
     }
}

Any ideas or suggestions?

Thanks!

Josh

A: 

I think the problem is that you're calling this.Items.Add() instead of this.Add(). The Items property returns the base List<T>, whose Add() method doesn't have the functionality you want.

Ben M
Thanks Ben... that seemed to do the trick...On another note, do you know anything about BindingList<T> using an object's Equals() method to determine which list item has changed?I ask because my custom objects all have a custom implementation of IEquatable, and it looks like whenever PropertyChanged event is triggered, each objects Equals() method is called until one of them returns true...
Joshua Barker
BindingList<T>'s PropertyChanged handler uses List<T>.IndexOf(), which (indirectly) calls your implementation of IEquatable<T>.Equals(). There's no way to thwart this behavior, so if you're concerned about performance but absolutely must use BindingList<T>, you might consider extracting your comparison logic to a separate class implementing IComparer<T> -- if that's at all feasible in your scenario.
Ben M
OK... it wasn't critical that I specifically override the IEquatable implementation, so I created an abstract method in my generic base instead : public abstract bool EqualTo(T obj); This solved my problem...Thanks again!
Joshua Barker