【问题标题】:CompositeCollection/CollectionViewSource confusionCompositeCollection/CollectionViewSource 混淆
【发布时间】:2013-05-22 22:56:15
【问题描述】:

我对使用这些类型时数据绑定的工作方式有点困惑。

我了解到您不能执行以下操作

public partial class Window1 : Window
    {
        public ObservableCollection<string> Items { get; private set; }

        public Window1()
        {
            Items = new ObservableCollection<string>() { "A", "B", "C" };
            DataContext = this;
            InitializeComponent();
        }
    }

<Window x:Class="WpfApplication25.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ComboBox>
        <ComboBox.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Items}"/>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>
</Window>

因为 CompositeCollection 没有数据上下文的概念,因此在其中使用绑定的任何内容都必须设置 Source 属性。如以下:

<Window x:Class="WpfApplication25.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources>
        <CollectionViewSource x:Key="list" Source="{Binding Items}"/>
    </Window.Resources>

    <ComboBox Name="k">
        <ComboBox.ItemsSource>
            <CompositeCollection>
               <CollectionContainer Collection="{Binding Source={StaticResource list}}"/>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>
</Window>

但它是如何工作的?它将源设置为某些东西,但是那个东西,在这种情况下, CollectionViewSource 使用数据上下文(因为它没有显式设置源)。

那么既然“list”是在Window的资源中声明的,是不是意味着它得到了Windows DataContext呢?在这种情况下,为什么以下方法也不起作用?

<Window x:Class="WpfApplication25.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources>
        <Button x:Key="menu" Content="{Binding Items.Count}"/>
    </Window.Resources>

    <ComboBox Name="k">
        <ComboBox.ItemsSource>
            <CompositeCollection>
                <ContentPresenter Content="{Binding Source={StaticResource menu}}"/>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>
</Window>

【问题讨论】:

    标签: wpf datacontext collectionviewsource staticresource compositecollection


    【解决方案1】:

    你是对的 CompositeCollection 没有 datacontext 的概念,所以它不能从它的父级继承它。

    来自 MSDN:
    CompositeCollection can contain items such as strings, objects, XML nodes, elements, as well as other collections. An ItemsControl uses the data in the CompositeCollection to generate its content according to its ItemTemplate. For more information about using ItemsControl objects to bind to collections, see the Binding to Collections section of the Data Binding Overview.

    回答你的问题
    But how is that working? it sets the source to something, but that something, in this case a CollectionViewSource uses a DataContext (as its not explicitly setting a source).

    我猜你想多了,Collection DependecyProperty 可以绑定到任何IEnumerable 类型,所以集合的创建方式并不重要,只要它创建并实现IEnumerable
    在您的情况下,CVS 从 Window 继承 DataContext,然后绑定到 Items

    关于您的第二个示例,它不起作用,因为 ContentPesenter 需要 dataContext 才能工作,因此因为它可以继承它,所以即使您尝试将内容 Source 绑定到按钮,绑定机制也只是将自己设置为 dataContext,您忘了设置路径,我想这就是它被忽略的原因。 要想让它工作,你所要做的就是这样设置:

    <ContentPresenter Content="{Binding Source={StaticResource menu}, Path=Content}"/
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 2014-05-06
      • 2015-02-02
      • 2011-05-11
      • 2012-06-02
      • 2012-08-15
      • 2019-06-26
      相关资源
      最近更新 更多