How do I convert a ComboBox to use a bound CompositeCollection?

北战南征 提交于 2019-12-04 02:06:38

问题


I have a ComboBox that has a bound items source... I've stripped my example down to the key pieces:

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

This works, but I now want to add a single manual item to my combobox that will trigger alternate functionality called "Other..." so I'm having to move to using the CompositeCollection... like so:

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

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

Try as I might, the bound items just won't populate when using the CompositeCollection. It only shows the manual ComboBoxItem "Other...". If I remove that item, the list is empty. If I attach a breakpoint to the converter it doesn't catch anything, which seems to indicate that the binding isn't even attempted.

I am obviously not understanding something about how the binding function in the CompositeCollection is happening. Can someone see an error in my XAML or explain what I'm missing?


回答1:


Declare the CompositeCollection in ComboBox.Resources and use it with 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}}" />

If you declare the CompositeCollection inside the ItemsSource property in element syntax, the Binding for the CollectionContainer.Collection doesn't find its DataContext.

Inside the Resources section, Freezables like CompositeCollection inherit the DataContext of their declaring element, as if they were logical children of the element. However, this is a speciality of the Resources property and properties like ContentControl.Content or similar properties which contain the logical children of a control (and maybe a few others). If you use element syntax to set the value of a property, in general you would have to expect that property value inheritance for properties like DataContext doesn't work, and so Bindings without an explicit Source won't work, either.



来源:https://stackoverflow.com/questions/12750784/how-do-i-convert-a-combobox-to-use-a-bound-compositecollection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!