wpf - CompositeCollection/CollectionViewSource 混淆

标签 wpf datacontext collectionviewsource staticresource compositecollection

我对使用这些类型时数据绑定(bind)的工作原理有点困惑。

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

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 没有数据上下文的概念,因此其中使用绑定(bind)的任何内容都必须设置 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>

最佳答案

你是对的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 可以绑定(bind)到任何 IEnumerable类型,因此只要集合创建并实现 IEnumerable ,集合的创建方式并不重要。 .
在您的情况下,CVS 从 Window 继承 DataContext,然后绑定(bind)到 Items

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

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

关于wpf - CompositeCollection/CollectionViewSource 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16702914/

相关文章:

c# - 设置图像源

wpf - 将控件绑定(bind)到两个属性

linq-to-sql - 在 Linq to Sql 中使用 UoW 模式失去数据绑定(bind)的可能性

c# - Azure 表 InsertOrMerge 更新插入 : Can the to-be-merged object be dynamically created?

wpf - 异步 CollectionViewSource 过滤?

wpf - 在 DataTemplate 中绑定(bind) CollectionViewSource

c# - 如何在我的场景中使用 MVVM 动态更新数据网格

wpf - 绑定(bind)到 C#/WPF 中 DataTable 中包含句点的字段

c# - Linq 和数据上下文

c# - ICollectionView.SortDescriptions 不适用于 boolean 值