Объединенный наблюдательный коллектив
У меня есть два ObservableCollections, и мне нужно показать их в одном элементе управления ListView. Для этого я создал MergedCollection, который представляет эти две коллекции как один ObservableCollection. Таким образом, я могу установить ListView.ItemsSource в мою объединенную коллекцию и обе коллекции. Добавление работ отлично, но когда я пытаюсь удалить элемент, отображается необработанное исключение:
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
}
Привет
Ответы
Ответ 1
Есть ли причина, по которой вы не можете использовать CompositeCollection?
Причина исключения заключается в том, что вы не переводите индексы внутренних коллекций во внешний. Вы просто передаете то же самое событие args внешнему событию (на MergedCollection
), поэтому WPF не находит элементы, в которых индекс сообщает ему, чтобы найти их.
Ответ 2
Вы должны компенсировать индекс события уведомления.
Предположим, что вы удаляете элемент из первой коллекции в индексе 2. Событие с изменением коллекции запускается с индексом 2.
Если вы удаляете элемент из второго набора по индексу 2, событие запускается с тем же индексом (2), но элемент фактически перечислит после всех элементов в первой коллекции.