在我最近提出的另一个问题中,有人告诉我要使用CompositeCollection
来访问ListBox
的各种来源。
示例使用了XmlDataProvider
来提供一些虚拟数据。但是,我有一个包含数据的视图模型。
我花了一些时间将我的ListBox
与视图模型的数据绑定起来。最终我搞定了,但现在我想知道为什么我的以前的尝试没有成功。
成功的关键是CollectionViewSource。我的最初尝试是:
<CollectionContainer Collection="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Movies}"/>
<CollectionContainer Collection="{Binding ElementName=Window, Path=DataContext.Movies}"/>
我的想法是找到具有适当DataContext的Window,并针对数据进行绑定。您可以通过
FindAncestor
或通过ElementName
来实现,因此我尝试了两种方法。这对我来说似乎非常合理,但显然我错了。当我运行应用程序时,我什么也没看到。我还尝试了针对具有数据上下文的另一个控件进行绑定;例如
StackPanel
。
那么,为什么我不能使用FindAncestor
和ElementName
1获取数据,而必须显式提供CollectionViewSource
呢?
这是运行正常的代码。
<StackPanel DockPanel.Dock="Top">
<ListBox ItemTemplateSelector="{StaticResource CustomDataTemplateSelector}">
<ListBox.Resources>
<CollectionViewSource x:Key="ViewSource" Source="{Binding Movies}"/>
</ListBox.Resources>
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource ViewSource}}"/>
<CollectionContainer Collection="{Binding Source={StaticResource MyButtonsData}}"/>
</CompositeCollection>
</ListBox.ItemsSource>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"
Width="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</StackPanel>
1 不,我没有忘记给窗口命名,也没有打错字。