0

I have a CollectionViewSource for my ComboBox. Now I want to add an 'empty element' or a 'null element' to the collection. To give the use the ability deselect the current selection.

Normally, I would use a CompositeCollection for this task (like this), since I don't want to handle such things in my ViewModel or in code-behind (.xaml.cs).

Here are the related code snippets:

<UserControl.Resources>
    <CollectionViewSource x:Key="FooItemsCollection" Source="{Binding FooItems}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="Name" />
        </CollectionViewSource.SortDescriptions>
     </CollectionViewSource>
</UserControl.Resources>

<ComboBox SelectedItem="{Binding SelectedFooItem, Mode=TwoWay}" 
          ItemsSource="{Binding Source={StaticResource FooItemsCollection}}"
          IsSynchronizedWithCurrentItem="False"
          DisplayMemberPath="Name" />

Is there any nice solution for this?

EDIT It is necessary, that SelectedFooItem will be set to null, when selecting this null-element.

ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
  • you empty element should be basically a flat button if i understand correctly. Check this if it can help you https://stackoverflow.com/questions/44564928/wpf-add-a-button-in-a-combobox-defined-in-datatemplate – Daniele Sartori Mar 08 '18 at 09:28
  • @DanieleSartori This will result in an binding error, which is indicated by a red border in the view. The setter of `SelectedFooItem` also won't hit. I have edited my question. – ˈvɔlə Mar 08 '18 at 09:32
  • you can work with the selection changed event. If the selected item is not of type "FooItem" set Selected item to null, and instead of a button you add a fake combobox item which contains a textblock for instance – Daniele Sartori Mar 08 '18 at 09:39
  • 1
    @DanieleSartori To quote myself: "I don't want to handle such things in my ViewModel or in code-behind". I cannot believe there is no xaml-only based solution for such thing. – ˈvɔlə Mar 08 '18 at 09:43

1 Answers1

2

Try this

        <ComboBox SelectedItem="{Binding SelectedFooItem, Mode=TwoWay}" 
  IsSynchronizedWithCurrentItem="False"
  DisplayMemberPath="Name" >
            <ComboBox.ItemsSource>
                    <CompositeCollection>
                        <CollectionContainer Collection="{Binding Source={StaticResource FooItemsCollection}}" />
                        <ComboBoxItem>
                            <TextBlock Content="NotAFoo"></Button>
                        </ComboBoxItem>
                    </CompositeCollection>
            </ComboBox.ItemsSource>
            <ComboBox.Style>
                <Style TargetType="{x:Type ComboBox}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=SelectedItem.Content}" Value="NotAFoo">
                            <Setter Property="SelectedItem" Value="{x:Null}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ComboBox.Style>
        </ComboBox>

Check if this work. I don't have time now to build a test environment, and it would be surely faster if you try it in your app.

Daniele Sartori
  • 1,674
  • 22
  • 38