我有一些包含音符的级联容器,其中有一个主容器,其中包含所有音符。 notes容器是在树状结构中制作的,在树形结构中越深越具体。我只有一个列表的原因与数据的非常复杂的管理有关,而不是问题的一部分。
主注释容器有一个ObservableCollection,所有子注释容器都通过CollectionView绑定到ObservableCollection。子笔记容器有一个过滤器,可以过滤掉它们的笔记。在常规代码中,一切正常,视图总是显示元素,但是当我将它们绑定到e时。 G。 ListBox,元素不会被过滤,主列表中的所有元素都会在没有过滤的情况下显示。当然我知道有一个ListCollectionView,但由于CollectionView来自IEnumerable,我很好奇ListBox如何访问主列表,如果它不从CollectionView访问SourceCollection。
换句话说,我不太清楚为什么我需要ListCollectionView来实现ColletionView适合的非常基本的行为。在我看来,ListCollectionView是必需的,而其他视图真的不适合ListBox吗?
这是一个小样本
XAML:
<Window x:Class="ListCollection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Horizontal">
<ListBox Width="100" ItemsSource="{Binding Model}"></ListBox>
<ListBox Width="100" ItemsSource="{Binding View1}"></ListBox>
<ListBox Width="100" ItemsSource="{Binding View2}"></ListBox>
</StackPanel>
</Window>
C#:
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
namespace ListCollection
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ObservableCollection<int> Model
{
get;
private set;
}
public ICollectionView View1
{
get;
private set;
}
public ICollectionView View2
{
get;
private set;
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
Model = new ObservableCollection<int>();
View1 = new CollectionView(Model);
View1.Filter = (o) =>
{
return ((int)o) > 50;
};
View2 = new CollectionView(View1);
View2.Filter = (o) =>
{
return ((int)o) > 70;
};
for (int i = 0; i < 100; i++)
Model.Add(i);
}
}
}
由于 马丁
答案 0 :(得分:3)
CollectionView class文档备注部分的第一行说:
您不应在代码中创建此类的对象。
所以,我猜它可能不是按照你使用它的方式设计的。
我总是使用CollectionViewSource.GetDefaultView(collection)
(最终会为ListCollectionView
返回ObservableCollection<T>
,但会以ICollectionView
的形式返回。
编辑:希望清楚一些事情,这里有一些关于集合视图的其他信息。
在Data Binding Overview文档页面上有一个相当不错的集合视图概述,这是一个很好的阅读。它解释了为什么每个集合都有一个默认视图。只要集合用作数据绑定的源,它就由框架创建。 GetDefaultView
方法获取该视图(如果它尚不存在则创建它)。对该方法的后续调用将始终返回相同的视图。
如果将ItemsControl.ItemsSource
直接绑定到集合,它将使用默认视图。因此,绑定到默认视图并绑定到集合本身具有相同的结果。如果要在同一个集合中拥有多个视图,那么您将需要创建自己的集合视图并明确绑定到这些视图,而不是绑定到集合或默认视图。
创建集合视图有几种方法,具体取决于您是从代码还是xaml创建它们。
从Viewmodel代码创建
创建一个新的ListCollectionView
,将集合传递给构造函数。如果您在viewmodel代码中,则可以将视图公开为属性(通常为ICollectionView
类型)。
Viewmodel代码:
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;
}
查看代码:
<ItemsControl ItemsSource="{Binding MyView}" />
从XAML视图创建
创建CollectionViewSource
并将其Source
属性设置为集合。您还可以设置其他属性,例如Filter
,它将调用代码隐藏来运行过滤器。
Viewmodel代码:
private ObservableCollection<Item> mItems;
public IEnumerable<Item> Items { get { return mItems; } }
public MyVM()
{
mItems = new ObservableCollection<Item>();
}
查看代码:
<Grid>
<Grid.Resources>
<CollectionViewSource
x:Key="MyItemsSource"
Source="{Binding Items}" />
</Grid.Resources>
<ItemsControl ItemsSource="{Binding Source={StaticResource MyItemsSource}}" />
</Grid>