3

Ich habe eine Hierarchie von Objekten, die alle INotifyPropertyChanged implementieren. Ich habe auch eine benutzerdefinierte Liste, die von BindingList abgeleitet ist.Wo/Wann/Wie funktioniert BindingList <T> convert/wireca PropertyChanged zu ListChanged Ereignis

Es ist mein Verständnis, dass, wenn ich ein Objekt hinzufügen, die Implements INotifyPropertyChanged der Liste, dass irgendwie das PropertyChanged-Ereignis wird automatisch auf das ListChanged-Ereignis verdrahtet/konvertiert.

Nachdem ich jedoch meine Liste als Datenquelle meiner DataGridView festgelegt habe, wenn ich einen Wert im Raster ändere, wird das ListChanged-Ereignis nicht ausgelöst ... Wenn ich in den Code eintrete, stellt sich heraus, dass die PropertyChanged () Ereignis löst keine becaue es null ist, was ich meine, davon ausgehen, dass es nicht immer verdrahtet-up/zum Listchanged-Ereignis des Binding umgewandelt, wie seine vermeintlichen ...

zum Beispiel:

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

Und hier ist meine benutzerdefinierte Liste Klasse ...

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

Irgendwelche Ideen oder Vorschläge?

Danke!

Josh

Antwort

2

Ich denke, das Problem ist, dass Sie this.Items.Add() statt this.Add() sind aufgerufen wird. Die Items-Eigenschaft gibt die Basis List<T> zurück, deren Add()-Methode nicht über die gewünschte Funktionalität verfügt.

+0

Dank Ben ... den Trick zu tun schien ... Auf einer anderen Anmerkung, wissen Sie etwas über Binding ein Objekt equals() Methode, die Listenposition zu bestimmen, unter Verwendung geändert hat? Ich frage, weil meine benutzerdefinierten Objekte alle eine benutzerdefinierte Implementierung von IEquatable haben, und jedes Mal, wenn das PropertyChanged-Ereignis ausgelöst wird, jede Equals() -Methode aufgerufen wird, bis eine von ihnen True zurückgibt ... –

+0

BindingList 's PropertyChanged-Handler verwendet die Liste .IndexOf(), die (indirekt) Ihre Implementierung von IEquatable .Equals() aufruft. Es gibt keine Möglichkeit, dieses Verhalten zu vereiteln, also sollten Sie die BindingList unbedingt verwenden, sollten Sie Ihre Vergleichslogik in eine separate Klasse implementieren, die IComparer implementiert - falls dies in Ihrem Szenario überhaupt möglich ist. –

+0

OK ... es war nicht kritisch, dass ich die IEquatable-Implementierung speziell überschreibe, also habe ich stattdessen eine abstrakte Methode in meiner generischen Basis erstellt: public abstract bool EqualTo (T obj); Dies löste mein Problem ... Danke nochmal! –