C# 合并的 ObservableCollection
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/777048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Merged ObservableCollection
提问by Zefo
I have two ObservableCollections and I need to show them in one ListView control together. For this purpose I created MergedCollection which presents these two collections as one ObservableCollection. This way I can set the ListView.ItemsSource to my merged collection and both collections are listed. Adding works fine but when I try to Remove an item, unhandled exception is shown:
我有两个 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'.
The code of MergedCollection follows:
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
}
Regards
问候
采纳答案by Kent Boogaart
Is there any reason you can't use CompositeCollection?
有什么理由不能使用CompositeCollection吗?
The reason the exception is being thrown is because you're not translating the indexes of the inner collections to the outer. You're just passing the exact same event args to the outer event (on MergedCollection
), which is why WPF doesn't find the items where the index is telling it to find them.
抛出异常的原因是您没有将内部集合的索引转换为外部集合。您只是将完全相同的事件参数传递给外部事件 (on MergedCollection
),这就是 WPF 找不到索引告诉它要查找它们的项目的原因。
You use a CompositeCollection
like so:
你使用CompositeCollection
这样的:
<ListBox>
<ListBox.Resources>
<CollectionViewSource x:Key="DogCollection" Source="{Binding Dogs}"/>
<CollectionViewSource x:Key="CatCollection" Source="{Binding Cats}"/>
</ListBox.Resources>
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource DogCollection}}"/>
<CollectionContainer Collection="{Binding Source={StaticResource CatCollection}}"/>
</CompositeCollection>
</ListBox.ItemsSource>
<!-- ... -->
</ListBox>
For details, see this answer.
有关详细信息,请参阅此答案。
回答by Josh G
You have to offset the index of the notification event.
您必须偏移通知事件的索引。
Say you remove an item from the first collection at index 2. A collection changed event is fired with index 2.
假设您从索引 2 处的第一个集合中删除了一个项目。集合已更改事件将使用索引 2 触发。
If you remove an item from the second collection at index 2, the event is fired with the same index (2), but the item is actually enumerated after all of the items in the first collection.
如果您从索引 2 处的第二个集合中删除一个项目,则使用相同的索引 (2) 触发该事件,但该项目实际上是在第一个集合中的所有项目之后枚举的。