2009-04-22 2 views
12

У меня есть два ObservableCollections, и мне нужно показать их в одном элементе управления ListView. Для этого я создал MergedCollection, который представляет эти две коллекции как один ObservableCollection. Таким образом, я могу установить ListView.ItemsSource в мою объединенную коллекцию и обе коллекции. Добавление работает нормально, но когда я пытаюсь удалить элемент, необработанное исключение показано:Объединенный ObservableCollection

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

Код MergedCollection следующим образом:

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 
} 

С уважением

ответ

21

Есть ли какой-либо причине вы не можете используйте CompositeCollection?

Причина исключения заключается в том, что вы не переводите индексы внутренних коллекций во внешний. Вы просто передаете то же самое событие args внешнему событию (на MergedCollection), поэтому WPF не находит элементы, в которых указатель говорит об этом, чтобы найти их.

+0

CompositeCollection не реализует INotifyCollectionChanged. –

+1

@Josh: Если вы перейдете по ссылке, вы увидите, что это так. –

+0

:-). Вы правы, Кент. Отлично. Я пошел по ссылке, но я не заметил, что интерфейсы, которые реализует коллекция, находятся на двух строках! Я видел только Илиста! –

4

Вы должны компенсировать индекс события уведомления.

Допустим, вы удалить элемент из первой коллекции с индексом 2. Коллекция изменено событие вызывается с индексом 2.

При удалении элемента из второй коллекции по индексу 2, событие вызывается с тот же индекс (2), но элемент фактически перечисляется после всех элементов в первой коллекции.

+0

Решение Kent лучше, но для записи вот что было изначально неправильно с вашим классом. –

+0

Спасибо, теперь я понимаю проблему. Сообщения об исключениях иногда немного сложны для меня. – Zefo

Смежные вопросы