Em1*_*Em1 5 data-binding wpf compositecollection collectionviewsource
在我最近提出的另一个问题中,我被告知使用a CompositeCollection来访问各种来源ListBox.
该示例使用a XmlDataProvider来提供一些虚拟数据.但是,我有一个包含数据的视图模型.
我花了一些时间来绑定ListBox视图模型的数据.最终我明白了,但现在我想明白为什么我以前的方法不起作用.
成功的关键是CollectionViewSource.我最初的尝试是:
<CollectionContainer Collection="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Movies}"/>
<CollectionContainer Collection="{Binding ElementName=Window, Path=DataContext.Movies}"/>
Run Code Online (Sandbox Code Playgroud)
我的想法是找到具有相应DataContext的Window,并绑定数据.你可以通过FindAncestor或通过ElementName,所以我尝试了两个.这对我来说似乎很合乎逻辑,但显然我错了.我运行应用程序时没有看到任何内容.
我还尝试绑定另一个具有数据上下文的控件; 例如StackPanel.
那么,为什么我不用1FindAncestor和ElementName1获取数据,但必须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>
Run Code Online (Sandbox Code Playgroud)
1不,我没有忘记给窗户命名,也没有打字错误.
我在microsoft.com上发现了一个讨论该问题的帖子.
似乎这个'bug'已知多年,但从未被修复过.
我CollectionViewSource也在那里使用我正在使用的解决方法.
此外,你确实不能使用ElementName.我不知道是什么原因,但解决办法ElementName是使用x:Reference如在其他问题的线程建议.
<CollectionContainer Collection="{Binding Source={x:Reference dummy}, Path=DataContext.Movies}"/>
Run Code Online (Sandbox Code Playgroud)
有趣的是,XAML编译器object reference not set to an instance of an object在编辑时会显示错误.
如果您没有使用祖先类型,则可以编译并运行,因为由于循环依赖性,您将获得XmlParseException.
要避免循环依赖性错误,可以将CompositeCollection放在资源中并通过StaticResource链接到那里.然后你也可以使用祖先类型.
<ListBox.Resources>
<CompositeCollection x:Key="CompositeCollection">
<CollectionContainer Collection="{Binding Source={x:Reference stackPanel}, Path=DataContext.Movies}"/>
</CompositeCollection>
</ListBox.Resources>
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource CompositeCollection}}"/>
</CompositeCollection>
</ListBox.ItemsSource>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2589 次 |
| 最近记录: |