2009-04-22 10 views
12

Tengo dos ObservableCollections y necesito mostrarlos juntos en un control ListView. Para este propósito creé MergedCollection que presenta estas dos colecciones como una ObservableCollection. De esta forma, puedo establecer ListView.ItemsSource en mi colección fusionada y se muestran ambas colecciones. Añadiendo funciona bien, pero cuando intento eliminar un elemento, se muestra excepción no controlada:Merged ObservableCollection

An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dll 
Additional information: Added item does not appear at given index '2'. 

El código de MergedCollection sigue:

public class MergedCollection : IEnumerable, INotifyCollectionChanged 
{ 
    ObservableCollection<NetworkNode> nodes; 
    ObservableCollection<NodeConnection> connections; 

    public MergedCollection(ObservableCollection<NetworkNode> nodes, ObservableCollection<NodeConnection> connections) 
    { 
     this.nodes = nodes; 
     this.connections = connections; 

     this.nodes.CollectionChanged += new NotifyCollectionChangedEventHandler(NetworkNodes_CollectionChanged); 
     this.connections.CollectionChanged += new NotifyCollectionChangedEventHandler(Connections_CollectionChanged); 
    } 

    void NetworkNodes_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     CollectionChanged(this, e); 
    } 

    void Connections_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     CollectionChanged(this, e); 
    } 

    #region IEnumerable Members 

    public IEnumerator GetEnumerator() 
    { 
     for (int i = 0; i < connections.Count; i++) 
     { 
      yield return connections[i]; 
     } 

     for (int i = 0; i < nodes.Count; i++) 
     { 
      yield return nodes[i]; 
     } 
    } 

    #endregion 

    #region INotifyCollectionChanged Members 

    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    #endregion 
} 

Saludos

Respuesta

21

¿Hay alguna razón por la que no se puede usar CompositeCollection?

La razón por la cual se lanza la excepción es porque no está traduciendo los índices de las colecciones internas al exterior. Solo está transfiriendo exactamente los mismos eventos args al evento externo (en MergedCollection), por lo que WPF no encuentra los elementos donde el índice indica que los encuentre.

+0

CompositeCollection no implementa INotifyCollectionChanged. –

+1

@Josh: si sigues el enlace, verás que sí. –

+0

:-). Tienes razón, Kent. Eso es perfecto. Seguí el enlace, ¡pero no me di cuenta de que las interfaces que implementa la colección están en dos líneas! ¡Solo vi IList! –

4

Tiene que compensar el índice del evento de notificación.

Digamos que eliminar un elemento de la primera colección en el índice 2. Un evento cambiado colección se disparó con índice 2.

Si elimina un elemento de la segunda colección en el índice 2, el evento se dispara con el mismo índice (2), pero el artículo en realidad se enumera después de todos los artículos en la primera colección.

+0

La solución de Kent es mejor, pero para el registro, esto es lo que originalmente estaba mal con su clase. –

+0

Gracias, ahora entiendo el problema. Los mensajes de excepción a veces son un poco difíciles para mí. – Zefo

Cuestiones relacionadas