¿Para qué sirve ObservableCollection en .net?

227

¿Para qué sirve ObservableCollection en .net?

santosh singh
fuente
1
@ alpha-mouse: ¿Puede dar un poco más de información sobre el problema que está tratando de resolver? Esto ayudará a las personas a darle ejemplos relevantes.
Jazza
@Jazza: Acabo de cambiar las etiquetas de la pregunta =) No soy la pregunta de santosh
alpha-mouse
3
@TheMuffinMan es cierto, pero prefiero la forma en que se explican las cosas en stackoverflow en comparación con la forma demasiado rígida a formal de MSDN de explicar sus propias creaciones.
Sizons

Respuestas:

224

ObservableCollection es una colección que permite que el código fuera de la colección sepa cuándo ocurren cambios en la colección (agregar, mover, eliminar). Se usa mucho en WPF y Silverlight, pero su uso no se limita a allí. El código puede agregar controladores de eventos para ver cuándo ha cambiado la colección y luego reaccionar a través del controlador de eventos para realizar un procesamiento adicional. Esto puede estar cambiando una IU o realizando alguna otra operación.

El código a continuación en realidad no hace nada, pero demuestra cómo adjuntar un controlador en una clase y luego usar los argumentos del evento para reaccionar de alguna manera a los cambios. WPF ya tiene muchas operaciones, como actualizar la interfaz de usuario integrada para que pueda obtenerlas de forma gratuita al usar ObservableCollections

class Handler
{
    private ObservableCollection<string> collection;

    public Handler()
    {
        collection = new ObservableCollection<string>();
        collection.CollectionChanged += HandleChange;
    }

    private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
    {
        foreach (var x in e.NewItems)
        {
            // do something
        }

        foreach (var y in e.OldItems)
        {
            //do something
        }
        if (e.Action == NotifyCollectionChangedAction.Move)
        {
            //do something
        }
    }
}
Craig Suchanec
fuente
21
e.NewItems& e.OldsItemspuede ser nulo dependiendo de la acción. Puede tirar NullReferenceException.
dovid
77
nota al margen: cuando Action es Move, el elemento movido aparecerá tanto en NewItems como en OldItems
bohdan_trotsenko
Gracias por esto:> WPF ya tiene muchas operaciones como actualizar la interfaz de usuario integrada para que pueda obtenerlas de forma gratuita al usar ObservableCollections
SlowLearner
157

Un ObservableCollectionfunciona esencialmente como una colección normal, excepto que implementa las interfaces:

Como tal, es muy útil cuando desea saber cuándo ha cambiado la colección. Se activa un evento que le dirá al usuario qué entradas se han agregado / eliminado o movido.

Más importante aún, son muy útiles cuando se utiliza el enlace de datos en un formulario.

Liz
fuente
54

Desde Pro C # 5.0 y .NET 4.5 Framework

los ObservableCollection<T> clase es muy útil porque tiene la capacidad de informar a los objetos externos cuando su contenido ha cambiado de alguna manera (como puede suponer, trabajar con él ReadOnlyObservableCollection<T>es muy similar, pero de solo lectura). En muchos sentidos, trabajar con ObservableCollection<T>es idéntico a trabajar con List<T>, dado que ambas clases implementan las mismas interfaces principales. Lo que hace que la ObservableCollection<T>clase sea única es que esta clase admite un evento denominadoCollectionChanged . Este evento se activará cada vez que se inserte un nuevo elemento, se elimine (o se reubique) un elemento actual o si se modifica toda la colección. Como cualquier evento, CollectionChanged se define en términos de un delegado, que en este caso es NotifyCollectionChangedEventHandler. Este delegado puede llamar a cualquier método que tome un objeto como primer parámetro, y unNotifyCollectionChangedEventArgscomo el segundo Considere el siguiente método Main (), que completa una colección observable que contiene objetos Person y conecta el CollectionChangedevento:

class Program
{
   static void Main(string[] args)
   {
     // Make a collection to observe and add a few Person objects.
     ObservableCollection<Person> people = new ObservableCollection<Person>()
     {
        new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
        new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
     };
     // Wire up the CollectionChanged event.
     people.CollectionChanged += people_CollectionChanged;
     // Now add a new item.
     people.Add(new Person("Fred", "Smith", 32));

     // Remove an item.
     people.RemoveAt(0);

     Console.ReadLine();
   }
   static void people_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
   {
       // What was the action that caused the event?
        Console.WriteLine("Action for this event: {0}", e.Action);

        // They removed something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        {
            Console.WriteLine("Here are the OLD items:");
            foreach (Person p in e.OldItems)
            {
                Console.WriteLine(p.ToString());
            }
            Console.WriteLine();
        }

        // They added something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        {
            // Now show the NEW items that were inserted.
            Console.WriteLine("Here are the NEW items:");
            foreach (Person p in e.NewItems)
            {
                Console.WriteLine(p.ToString());
            }
        }
   }
}

El NotifyCollectionChangedEventArgsparámetro entrante define dos propiedades importantes OldItemsy NewItems, que le dará una lista de elementos que estaban actualmente en la colección antes de que se desencadenara el evento, y los elementos nuevos que estuvieron involucrados en el cambio. Sin embargo, deseará examinar estas listas solo en las circunstancias correctas. Recuerde que el evento CollectionChanged puede activarse cuando se agregan, eliminan, reubican o restablecen elementos. Para descubrir cuál de estas acciones desencadenó el evento, puede usar la propiedad Acción de NotifyCollectionChangedEventArgs. La propiedad Action se puede probar con cualquiera de los siguientes miembros de la NotifyCollectionChangedActionenumeración:

public enum NotifyCollectionChangedAction
{
Add = 0,
Remove = 1,
Replace = 2,
Move = 3,
Reset = 4,
}

Miembros de System.Collections.ObjectModel

Dijo Roohullah Allem
fuente
1
¿Se activará el evento people_CollectionChanged si cambio el nombre de una persona en la colección (sin alterar la colección en sí?)
BKSpurgeon
25

Explicación sin código

Para aquellos que desean una respuesta sin ningún código detrás (boom-tish), levantaré la mano:

Colecciones normales: sin notificaciones

De vez en cuando voy a Nueva York y mi esposa me pide que compre cosas. Entonces llevo una lista de compras conmigo. La lista tiene muchas cosas como:

  1. Bolso Louis Vuitton ($ 5000)
  2. Perfume Clive Christian's Imperial Majesty ($ 215,000)
  3. Gafas de sol Gucci ($ 2000)

jajaja bueno, no estoy comprando esas cosas. Así que las tacho y las elimino de la lista y agrego en su lugar:

  1. 12 docenas de pelotas de golf Titleist.
  2. Bola de boliche de 12 lb.

Por lo general, vuelvo a casa sin los productos y ella nunca está contenta. Lo que pasa es que ella no sabe lo que quito de la lista y lo que agrego a ella; ella no recibe notificaciones.

The ObservableCollection - notificaciones cuando se realizan cambios

Ahora, cada vez que elimino algo de la lista: ¡recibe una notificación en su teléfono (es decir, sms / correo electrónico, etc.)!

La colección observable funciona de la misma manera. Si agrega o elimina algo de él o de él: alguien recibe una notificación. Y cuando se les notifique, entonces lo llamarán y recibirán un oído completo. Por supuesto, las consecuencias se pueden personalizar a través del controlador de eventos.

¡Eso lo resume todo!

BKSpurgeon
fuente
7

Uno de los usos más importantes es que puede vincular los componentes de la interfaz de usuario a uno y responderán de manera adecuada si el contenido de la colección cambia. Por ejemplo, si vincula un ItemSource de ListView a uno, el contenido de ListView se actualizará automáticamente si modifica la colección.

EDITAR: Aquí hay un código de muestra de MSDN: http://msdn.microsoft.com/en-us/library/ms748365.aspx

En C #, conectar el ListBox a la colección podría ser tan fácil como

listBox.ItemsSource = NameListData;

sin embargo, si no ha conectado la lista como un recurso estático y ha definido NameItemTemplate, puede anular ToString () de PersonName. Por ejemplo:

public override ToString()
{
    return string.Format("{0} {1}", this.FirstName, this.LastName);
}
Sean U
fuente
6

Es una colección que se utiliza para notificar principalmente a la interfaz de usuario para cambiar en la colección, admite notificación automática.

Utilizado principalmente en WPF,

Supongamos que tiene una interfaz de usuario con un cuadro de lista y un botón de agregar y cuando hace clic en el botón, un objeto de tipo suponga que se agregará una persona a la colección obseravable y vincula esta colección al ItemSource de Listbox, tan pronto como agregue un nuevo elemento en la colección, Listbox se actualizará y agregará un elemento más en él.

TalentTuner
fuente
Realmente esto sucede? : O
Reyes
5
class FooObservableCollection : ObservableCollection<Foo>
{
    protected override void InsertItem(int index, Foo item)
    {
        base.Add(index, Foo);

        if (this.CollectionChanged != null)
            this.CollectionChanged(this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, item, index);
    }
}

var collection = new FooObservableCollection();
collection.CollectionChanged += CollectionChanged;

collection.Add(new Foo());

void CollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
    Foo newItem = e.NewItems.OfType<Foo>().First();
}
abatishchev
fuente
¿Puedes explicar por qué FooObservableCollection implementó la colección? ¿Y por qué anulaste InsertItem?
Arie
@Arie: honestamente, 8 años después no lo recuerdo, así que no tengo idea. Por lo que veo en los documentos, no hay necesidad de nada de esto, todo debería salir de la caja.
abatishchev