我有某种包含笔记的级联容器,其中有一个主容器包含所有笔记。笔记容器以树状层次结构形式制作,树结构越深入,笔记容器就越具体。我只有一个列表的原因与非常复杂的数据管理有关,但这不是问题的一部分。
\n\n主注释容器有一个ObservableCollection,所有子注释容器都绑定到ObservableCollectionvia CollectionView。子注释容器有一个过滤器,可以过滤掉它们的注释。在常规代码中,一切正常,视图始终显示元素,但是当我将它们绑定到 eg 时ListBox,元素不会被过滤,并且主列表中的所有元素都会显示而不进行过滤。当然我知道有一个ListCollectionView,但是由于 CollectionView 来自IEnumerable,我很好奇如果它ListBox不从 访问 ,那么它如何访问主SourceCollection列表CollectionView。
换句话说,我不太确定为什么我需要应该适合的ListCollectionView非常基本的行为ColletionView。在我看来, 是ListCollectionView强制性的,而不是其他观点真正适合ListBox?
这是一个小样本
\n\nXAML:
\n\n<Window x:Class="ListCollection.MainWindow"\n xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"\n xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"\n Title="MainWindow" Height="350" Width="525">\n <StackPanel Orientation="Horizontal">\n <ListBox Width="100" ItemsSource="{Binding Model}"></ListBox>\n <ListBox Width="100" ItemsSource="{Binding View1}"></ListBox>\n <ListBox Width="100" ItemsSource="{Binding View2}"></ListBox>\n </StackPanel>\n</Window>\nRun Code Online (Sandbox Code Playgroud)\n\nC#:
\n\nusing System.Collections.ObjectModel;\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Data;\n\nnamespace ListCollection\n{\n /// <summary>\n /// Interaktionslogik f\xc3\xbcr MainWindow.xaml\n /// </summary>\n public partial class MainWindow : Window\n {\n public ObservableCollection<int> Model\n {\n get; private set;\n }\n\n public ICollectionView View1\n {\n get; private set;\n }\n\n public ICollectionView View2\n {\n get; private set;\n }\n\n public MainWindow()\n {\n InitializeComponent();\n\n DataContext = this;\n\n Model = new ObservableCollection<int>();\n View1 = new CollectionView(Model);\n View1.Filter = (o) =>\n {\n return ((int)o) > 50;\n };\n\n View2 = new CollectionView(View1);\n View2.Filter = (o) =>\n {\n return ((int)o) > 70;\n };\n\n for (int i = 0; i < 100; i++)\n Model.Add(i);\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n谢谢\n马丁
\nCollectionView 类文档备注部分的第一行内容如下:
您不应在代码中创建此类的对象。
所以,我猜它可能不是为您使用它的方式而设计的。
我总是使用CollectionViewSource.GetDefaultView(collection)(最终会返回一个ListCollectionViewfor ObservableCollection<T>,但它作为一个返回ICollectionView)。
编辑:为了希望澄清一些事情,这里有一些有关集合视图的附加信息。
数据绑定概述文档页面上有一个相当不错的集合视图概述,值得一读。它解释了为什么每个集合都有一个默认视图。每当集合用作数据绑定源时,框架都会创建它。该GetDefaultView方法获取该视图(如果尚不存在则创建它)。对该方法的后续调用将始终返回相同的视图。
如果将 anItemsControl.ItemsSource直接绑定到集合,它将使用默认视图。因此,绑定到默认视图和绑定到集合本身具有相同的结果。如果您希望同一集合中有多个视图,那么您将需要创建自己的集合视图并显式绑定到这些视图,而不是绑定到集合或默认视图。
有多种方法可以创建集合视图,具体取决于您是从代码还是 xaml 创建它们。
从 Viewmodel 代码创建
创建一个新的ListCollectionView,将集合传递给构造函数。如果您使用视图模型代码,则可以将视图公开为属性(通常为 类型ICollectionView)。
视图模型代码:
private ObservableCollection<Item> mItems;
public ICollectionView MyView { get; private set; }
public MyVM()
{
mItems = new ObservableCollection<Item>();
ListCollectionView myView = new ListCollectionView(mItems);
// Do whatever you want with the view here
MyView = myView;
}
Run Code Online (Sandbox Code Playgroud)
查看代码:
<ItemsControl ItemsSource="{Binding MyView}" />
Run Code Online (Sandbox Code Playgroud)
从 XAML 视图创建
创建一个集合CollectionViewSource并将其Source属性设置为集合。您还可以设置其他属性,例如Filter,它将调用隐藏代码来运行过滤器。
视图模型代码:
private ObservableCollection<Item> mItems;
public IEnumerable<Item> Items { get { return mItems; } }
public MyVM()
{
mItems = new ObservableCollection<Item>();
}
Run Code Online (Sandbox Code Playgroud)
查看代码:
<Grid>
<Grid.Resources>
<CollectionViewSource
x:Key="MyItemsSource"
Source="{Binding Items}" />
</Grid.Resources>
<ItemsControl ItemsSource="{Binding Source={StaticResource MyItemsSource}}" />
</Grid>
Run Code Online (Sandbox Code Playgroud)