2009-11-04 10 views
5

Me gustaría hacer algo de procesamiento antes de que un artículo se agregue a una lista de vinculación. Veo que hay un evento ListChanged pero se dispara después de que se agrega el elemento. El evento AddingNew solo se activa cuando se llama al método AddNew (no el método Add). ¿Alguien ha hecho algo así antes?¿Cómo puedo disparar el evento antes de agregar el elemento a la colección en C#?

ACTUALIZACIÓN:

he creado las siguientes clases y cuando el método Add se llama en la IList, mi nuevo método Add se desencadena. Entonces, ¿tengo el problema de transmisión que he leído en otros lugares? Si eliminé la interfaz ISpecialCollection de la colección, mi método Add no se llama. ¿Alguien puede explicar por qué está actuando de manera diferente? ¿Tengo el problema de transmisión si utilizo la interfaz ISpecialCollection <?

public interface ISpecialCollection<T> : IList<T> 
{ 
} 

public class SpecialCollection<T> : BindingList<T>, ISpecialCollection<T> 
{ 
    public new void Add (T item) 
    { 
    base.Add(item);  
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    IList<ItemType> list = new SpecialCollection<ItemType>(); 
    list.Add(new ItemType()); 
    } 
} 
+0

Jeff A.dice en alguna parte que el valor está muy guardado en caché, y que puede tomar un par de horas para actualizarse. –

Respuesta

3

Debe anular el método BindingList.InsertItem protegido (MSDN). Add, Insert y todos lo llaman para hacer la adición real de agregar y levantar eventos apropiados. Levante su evento, y luego llame al base.InsertItem para hacer el resto.

1

Algo así como:

public class PreProcessBindingList<T> : Collection<T> 
    { 
     public AddingNewEventHandler AddingNew; 

     public override void Add(T item) 
     { 
      PreProcess(item); 
      base.Add(item); 

      AddingNewEventHandler addingNew = this.AddingNew; 
      if (addingNew != null) 
      { 
       addingNew(this, new AddingNewEventArgs(item)); 
      } 
     } 
    } 
+0

Lo sé pero he oído que esto podría causar problemas si alguien lo lanza como una Lista y llama a Agregar. En ese caso, no se llamaría al nuevo método Add. – bsh152s

+0

Sí, querrás anularlo, no ocultarlo. –

+0

No puede anular el método BindingList.Add. Lo mejor que puedes hacer es esconderlo. – Ian

2

he hecho algo similar, ya que necesitaba para capturar el evento ItemAdding y ItemAdded

El bit de magia es la nueva palabra clave que va a sustituir la clase heredada método

// class that inherits generic List and hides the add item 
public class ListWithEvents<T> : List<T> 
    { 
     public event EventHandler ItemAdding; 
     public event EventHandler ItemAdded; 

     public new void Add(T item) 
     { 
      if (ItemAdding != null) 
       ItemAdding(item, EventArgs.Empty); 

      base.Add(item); 

      if (ItemAdded != null) 
       ItemAdded(item, EventArgs.Empty); 

     } 
    } 

// Using the class 
protected override void OnLoad(EventArgs e) 
    { 

     ListWithEvents<int> lstI = new ListWithEvents<int>(); 
     lstI.ItemAdded += new EventHandler(lstI_ItemAdded); 
     lstI.ItemAdding += new EventHandler(lstI_ItemAdding); 
    } 

    void lstI_ItemAdding(object sender, EventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 

    void lstI_ItemAdded(object sender, EventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 
3

La ruta más directa es la subclase Collection<T> clase. Esta es la clase de recopilación en el BCL que es diseñada para ser subclasificada y tener su comportamiento anulado. Subclasificar otros tipos como BindingList<T> o List<T> simplemente le causará dolor.

Una vez que subclase Collection<T>, puede anular Agregar y crear su propio evento para escuchar.

0

La forma correcta de hacerlo es ampliar Collection<T> y anular el método InsertItem. Puede plantear su evento allí antes de llamar a base.InsertItem.

0

Utilice la biblioteca de colecciones C5. Las colecciones de C5 ya están configuradas para poder activar eventos en varias operaciones, incluida la limpieza de la colección, la adición de elementos, la eliminación de elementos, la inserción de elementos y los cambios generales en la recopilación.

A su vez, las colecciones de bibliotecas C5 aplicar las System.Collection.GenericICollection y IList las interfaces en su caso, y así pueden ser dejados en como la aplicación incluso si una biblioteca sólo está esperando, por ejemplo, un SCG.ICollection.

EDIT: olvidé mencionar una parte de sus requisitos; muchos de esos eventos que mencioné anteriormente son eventos cancelables, y se activan antes de que la acción haya afectado la colección subyacente, lo que le permite realizar cambios o rechazar adiciones, eliminaciones, etc.

-1

Use ObservableCollection. Tiene eventos que monitorean cuando la colección está cambiando. Creo que se usa principalmente para WPF, pero también lo he usado con proyectos ASP.NET.

+1

... ObservableCollection (Of T) ... en el espacio de nombres System.Collections.ObjectModel en WindowsBase.dll. – crazytmack

+0

ObservableCollection solo tiene eventos de publicación, pero la pregunta es acerca de los eventos previos. Tendría que heredar de ObservableCollection e invalidar miembros para obtener el comportamiento deseado. –

Cuestiones relacionadas