2008-11-17 8 views
5

L'événement ListChanged d'une IBindingList déclenche un type ListChangedType.ItemDeleted lorsque des éléments sont supprimés, peut-être par un utilisateur qui supprime une ligne dans un contrôle DataGrid lié à la liste. Le problème est que le NewIndex dans la liste n'est pas valide dans cet événement, il a été supprimé et l'élément qui a été supprimé n'est pas disponible. Il devrait y avoir un événement ItemDeleting, mais je doute qu'ils puissent le réparer.dotnet: ListChangedType.ItemDeleted est inutile?

Répondre

8

Oui, c'est assez ennuyeux, mais il y a une solution de contournement facile. Je crée une classe BindingListBase<T> que j'utilise pour toutes mes listes au lieu d'utiliser un BindingList<T> normal. Parce que ma classe hérite du BindingList<T>, j'ai accès à tous ses membres protégés, y compris la méthode RemovedItem.

Ceci me permet de décrocher lorsqu'un élément est retiré. Vous pouvez faire ce que je fais et avoir une liste mRemovedItems à laquelle j'ajoute toujours des objets, ou soulevez votre propre événement 'ItemRemoved'.

Voir mon exemple de code ci-dessous:

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

Ce n'est pas vraiment prévu pour cela. NewIndex est l'index où se trouvait l'élément lors de sa suppression, et il est utile que les contrôles liés puissent localiser leur élément d'affichage associé dans leurs propres listes et le supprimer. Quel est le cas d'utilisation que vous voulez activer avec un ItemDeleting?

1

je l'ai fait quelque chose de semblable à ce que Adam a fait Valpied, à savoir mis en œuvre ma propre classe avec un ListChanging événement gestionnaire. Cela me permet de travailler avec l'élément qui est sur le point d'être retiré de la liste avant qu'il ne le fasse réellement. En réponse à la question de Sunlight concernant le cas d'utilisation ... entre autres choses, je l'utilise pour supprimer les gestionnaires d'événements qui ont été mis sur l'élément contenu quand il a été mis dans la liste. Mes éléments de données contiennent un niveau de gravité d'erreur, déterminé lors de la validation, et les éléments de l'interface utilisateur graphique, ils sont liés pour afficher cette gravité d'erreur en tant que couleur d'arrière-plan. Lorsque le niveau de gravité des erreurs de l'élément de données change, l'élément GUI doit être mis à jour. Je dois donc placer un gestionnaire d'événement HighestSeverityChanged sur l'élément de données lorsqu'il est affiché (seul ou dans le cadre d'une liste affichée), et j'ai besoin de supprimer ce gestionnaire d'événements lorsque l'élément de l'interface graphique n'est pas lié élément de données.

2

Voici ma version d'une classe BindingList qui implémente un événement itemRemoved, plutôt que de garder une liste secondaire des éléments supprimés

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