CompositeCollection + CollectionContainer: 将 CollectionContainer.Collection 绑定到 ViewModel 的属性,该属性用作 DataTemplates 的 DataType。

20

我无法正确使用绑定语法来访问 MyViewModel 中的 CatsDogs 属性,在一个定义了 CompositeCollectionDataTemplate 内部资源中。

public class MyViewModel
{
    public ObservableCollection<Cat> Cats { get; private set; }
    public ObservableCollection<Dog> Dogs { get; private set; }
}
<DataTemplate DataType={x:Type local:MyViewModel}">
  <DataTemplate.Resources>
    <CompositeCollection x:Key="MyColl">
      <!-- How can I reference the Cats and Dogs properties of MyViewModel? -->
      <CollectionContainer Collection="{Binding Dogs, ????}">
      <CollectionContainer Collection="{Binding Cats, ????}">
    </CompositeCollection>
  </DataTemplate.Resources>
  <ListBox ItemsSource="{StaticResource MyColl}">
    <!-- ... -->
  </ListBox>
</DataTemplate>

我需要插入什么内容来绑定DogsCats集合到CollectionContainer中?

2个回答

57

由于关于CollectionContainer上数据绑定的问题,如http://social.msdn.microsoft.com/Forums/vstudio/en-US/b15cbd9d-95aa-47c6-8068-7ae9f7dca88a/collectioncontainer-does-not-support-relativesource?forum=wpf所述,我现在采用以下方法:

<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>

编辑:CompositeCollection类不从FrameworkElement派生,因此没有DataContext属性来支持数据绑定。只有在提供Source的情况下使用Binding才能起作用。请参阅https://dev59.com/--o6XIcBkEYKwwoYSClJ#6446923以获取更多信息。


这对我很有帮助。但如果您能解释为什么需要这样做,那将更有帮助。我不理解:1)为什么我不能以相同的方式声明CollectionContainer资源并直接使用它,而要通过CollectionViewSource进行间接操作?2)为什么我不能声明CompositeCollection为一个资源,并直接在内部绑定到CollectionContainer对象?CollectionViewSource有什么特殊之处,使得即使其他类型无法工作,它也可以在这里起作用? - Peter Duniho

4

尝试给你的ListBox命名,并在绑定中引用它的DataContext

<ListBox x:Name="myList" ItemsSource="{DynamicResource MyColl}">
   <ListBox.Resources>
      <CompositeCollection x:Key="MyColl">
         <CollectionContainer Collection="{Binding DataContext.Dogs, Source={x:Reference myList}}"/>
         <CollectionContainer Collection="{Binding DataContext.Cats, Source={x:Reference myList}}"/>
      </CompositeCollection>
   </ListBox.Resources>
</ListBox>

这个不起作用。我得到了一个异常,无法解析“ListBox”的名称。我认为这是因为“CompositeCollection”在“DataTemplate.Resources”中声明,且“ListBox”在其后声明的原因。 - Oliver
只是一些建议... 为什么你想在模板资源中收集集合.. 你能把它移动到ListBox资源中吗? - Nitin
请使用 {DynamicResource MyColl} 替代 StaticResource - Nitin
循环引用:如果您在要引用的元素内使用x:Reference,则会出现此问题。这篇文章https://dev59.com/--o6XIcBkEYKwwoYSClJ也描述了这个问题。它说您必须将CompositeCollection移动到资源中并使用StaticResource-这是我尝试过的。但是,然后我不知道如何将CollectionContainer绑定到ViewModel属性。循环问题;-) - Oliver
1
如果您将collectin放入您的listbox资源中并使用dynamicresource引用它,则不会出现循环错误...刚刚测试了一下...工作正常...已使用测试过的代码更新答案。 - Nitin
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接