2008-11-17 6 views
5

Das ListChanged-Ereignis für eine IBindingList löst einen Typ ListChangedType.ItemDeleted aus, wenn Elemente gelöscht werden, möglicherweise weil ein Benutzer eine Zeile in einem DataGrid-Steuerelement löscht, das an die Liste gebunden ist. Das Problem besteht darin, dass der NewIndex in der Liste in diesem Fall ungültig ist. Er wurde gelöscht und das Element, das gelöscht wurde, ist nicht verfügbar. Es sollte ein ItemDeleting-Ereignis geben, aber ich bezweifle, dass es das jemals beheben wird.dotnet: ListChangedType.ItemDeleted ist nutzlos?

Antwort

8

Ja, es ist ziemlich nervig, aber es gibt einen einfachen Workaround. Ich erstelle eine Klasse, die ich für alle meine Listen anstelle einer normalen BindingList<T> verwenden. Da meine Klasse von der BindingList<T> erbt, habe ich Zugriff auf alle geschützten Elemente, einschließlich der RemovedItem-Methode.

Dadurch kann ich abholen, wenn ein Artikel entfernt wird. Sie könnten tun, was ich tue und eine mRemovedItems-Liste haben, der ich immer Elemente hinzufüge, oder Ihr eigenes "ItemRemoved" -Ereignis erheben.

Siehe mein Codebeispiel unten:

Public MustInherit Class BindingListBase(Of T) 
    Inherits BindingList(Of T) 

    Protected mRemovedItems As New List(Of T) 

    Protected Overrides Sub ClearItems() 
     MyBase.ClearItems() 
     mRemovedItems.Clear() 
    End Sub 

    Protected Overrides Sub RemoveItem(ByVal index As Integer) 
     Dim item As T = MyBase.Item(index) 

     MyBase.RemoveItem(index) 

     mRemovedItems.Add(item) 
    End Sub 

    Public ReadOnly Property RemovedItems as List(Of T) 
     Get 
      Return mRemovedItems 
     End Get 
    End Property 
End Class 
2

Es ist nicht wirklich für diesen Zweck gedacht. NewIndex ist der Index, in dem sich das Element befand, als es gelöscht wurde, und für gebundene Steuerelemente ist es hilfreich, das zugehörige Anzeigeelement in ihren eigenen Listen zu finden und zu entfernen.

Was ist der Anwendungsfall, den Sie mit einem ItemDeleting aktivieren möchten?

1

ich etwas tat, ähnlich dem, was Adam Valpied tat, das heißt meine eigene Klasse mit einem ListChanging Event-Handler implementiert. Dadurch kann ich mit dem Element arbeiten, das gerade aus der Liste entfernt wird, bevor es tatsächlich ausgeführt wird.

Als Antwort auf die Sunlight-Frage bezüglich des Anwendungsfalls ... benutze ich sie unter anderem, um Event-Handler zu entfernen, die auf das enthaltene Objekt gesetzt wurden, als es in die Liste aufgenommen wurde. Meine Datenelemente enthalten eine Fehlerschwerebene, die während der Überprüfung ermittelt wird, und die GUI-Elemente müssen diese Fehlerschwere als Hintergrundfarbe anzeigen. Wenn sich der Schweregrad des Datenelements ändert, muss das GUI-Element aktualisiert werden. Also muss ich einen EventHandler HighestSeverityChanged auf das Datenelement setzen, wenn es angezeigt wird (ob allein oder als Teil einer Liste, die angezeigt wird), und ich muss diesen Event-Handler entfernen, wenn das GUI-Element nicht gebunden ist Datenelement.

2

Hier ist meine Version einer Binding Klasse, die ein ItemRemoved Ereignis implementiert, anstatt eine sekundäre Liste der gelöschten Elemente halten

public class ItemRemovedEventArgs : EventArgs 
{ 
    public Object Item { get; set; } 

    public ItemRemovedEventArgs(Object item) 
    { 
     this.Item = item; 
    } 
} 

public delegate void ItemRmoveEventHandler(Object sender, ItemRemovedEventArgs e); 

public class BindingListRedux<T> : BindingList<T> 
{ 
    public BindingListRedux() : base() { } 

    public BindingListRedux(IList<T> list) : base(list) { } 

    public event ItemRmoveEventHandler ItemRemoved; 

    protected void OnItemRemoved(ItemRemovedEventArgs e) 
    { 
     if (ItemRemoved != null) 
     { 
      ItemRemoved(this, e); 
     } 
    } 

    protected override void RemoveItem(int index) 
    { 
     Object item = base[index]; 
     base.RemoveItem(index); 
     this.OnItemRemoved(new ItemRemovedEventArgs(item)); 
    } 
}