CompositeCollection/CollectionViewSource 混淆问题

7

当使用这些类型时,数据绑定是如何工作的,我有点困惑。

我读到过,你不能做以下操作

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>
1个回答

4

你是正确的,CompositeCollection 没有 datacontext 的概念,因此它无法从其父级继承。

来自 MSDN:
CompositeCollection可以包含诸如字符串、对象、XML节点、元素以及其他集合等项目。ItemsControl根据其ItemTemplate使用CompositeCollection中的数据生成其内容。有关使用 ItemsControl 对象绑定到集合的更多信息,请参阅 数据绑定概述 中的“绑定到集合”部分。

针对你的问题:
但是这是怎么工作的呢?它将源设置为某个东西,但是这个东西(在本例中为 CollectionViewSource)使用 DataContext(因为它没有显式设置源)

我想你想得太多了,Collection 依赖属性可以绑定到任何 IEnumerable 类型,因此只要创建并实现 IEnumerable 就可以了。 在你的情况下,CVS 继承了窗口的 DataContext,然后绑定到 Items

关于你的第二个示例,它不起作用是因为 ContentPresenter 需要 DataContext 才能正常工作,所以由于它无法继承,绑定机制仅将其自身设置为 DataContext,即使你尝试将 Source 绑定到按钮的内容也无效,因为你忘记了设置路径。 我想这就是它被忽略的原因。只需像这样设置即可使其正常工作:

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

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