如何将ComboBox转换为使用绑定的CompositeCollection?

时间:2012-10-05 16:57:45

标签: wpf xaml binding combobox compositecollection

我有一个ComboBox,它有一个绑定的项目源...我已经将我的例子剥离到了关键部分:

<UserControl x.Class="My.Application.ClientControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                         
             xmlns:conv="clr-namespace:My.Utilities.Converters"
             Name="ClientControl">

    <UserControl.Resources>
        <ResourceDictionary>
            <CollectionViewSource Key="x:ClientsCollection" />
        </ResourceDictionary>

        <conv:ClientOptions x:Key="ClientOptions" />

    </UserControl.Resources>

    ...

    <ComboBox Name="Options" 
              DataContext="ClientsCollection" 
              ItemsSource="{Binding [ClientNumber], Converter={StaticResource ClientOptions}" />

</UserControl>

这样可行,但我现在想在我的组合框中添加一个手动项,它将触发名为“Other ...”的替代功能,所以我不得不转而使用CompositeCollection ......就像这样:

<ComboBox Name="Options"
          DataContext="ClientsCollection">
    <ComboBox.ItemsSource>
        <CompositeCollection>

            <CollectionContainer Collection="{Binding [ClientNumber], Converter={StaticResource ClientOptions} />
            <ComboBoxItem>Other...</ComboBoxItem>
        </CompositeCollection>
</ComboBox>

尽可能尝试使用CompositeCollection时不会填充绑定项。它只显示手动ComboBoxItem“Other ...”。如果我删除该项目,则列表为空。如果我将一个断点附加到转换器上它没有捕获任何东西,这似乎表明甚至没有尝试绑定。

我显然不了解CompositeCollection中的绑定函数是如何发生的。有人可以在我的XAML中看到错误或解释我错过的内容吗?

1 个答案:

答案 0 :(得分:1)

在ComboBox.Resources中声明CompositeCollection,并将其与ItemsSource =“{Binding Source = {StaticResource myCompositeCollection}}”一起使用。

<UserControl x.Class="My.Application.ClientControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                         
         xmlns:conv="clr-namespace:My.Utilities.Converters"
         Name="ClientControl">

<UserControl.Resources>
    <ResourceDictionary>
        <CollectionViewSource Key="x:ClientsCollection" />
    </ResourceDictionary>

    <conv:ClientOptions x:Key="ClientOptions" />
    <CompositeCollection x:Key="myCompositeCollection">

        <CollectionContainer Collection="{Binding Source={StaticResource ClientsCollection}, Path=[ClientNumber], Converter={StaticResource ClientOptions} />
        <ComboBoxItem>Other...</ComboBoxItem>
    </CompositeCollection>

</UserControl.Resources>

...

<ComboBox Name="Options" 
          DataContext="ClientsCollection" 
          ItemsSource="{Binding Source={StaticResource myCompositeCollection}}" />

如果在元素语法中在ItemsSource属性中声明CompositeCollection,则CollectionContainer.Collection的Binding不会找到其DataContext。

在Resources部分中,像CompositeCollection这样的Freezables继承了它们的声明元素的DataContext,就像它们是元素的逻辑子元素一样。但是,这是Resources属性和属性(如ContentControl.Content)或类似属性(包含控件的逻辑子级(可能还有其他几个))的特性。如果使用元素语法来设置属性的值,通常您必须期望DataContext等属性的属性值继承不起作用,因此没有显式Source的Bindings也不起作用。