'WPF ComboBox with CheckBoxes display info about checked items?

Im trying to make a ComboBox that have checkboxes as items and based on what is checked display different things when the combobox is "closed".

The look Im trying achieve can be seen in the image.

enter image description here

Ideally I dont want the user to be able to select the text in the top ( in the image).

Is there a simple solution to this? I've seen solutions where one can display more information when all the items are shown by using DataTriggers to hide different nested controls, but that is not really what Im looking for.

Any ideas?

/Erik



Solution 1:[1]

Using a combination of the @Erik83 and @Xavier solution I still had the problem that selecting a ComboBoxItem in a location right from the CheckBox text closes the ComboBox-DropDown and shows the ToString() value of the ComboBoxItem as the CheckBox is not stretched to DropDown-Width. I solved it by adding

HorizontalContentAlignment="Stretch"

to the CheckBox and adding the ItemContainerStyle:

<ComboBox x:Name="combobox"
    Background="White"
    Padding="2"
    Text="{Binding ElementName=DockPanelTemplateComboCheck, Path=ComboTextFilter}"
    IsEditable="True"
    IsReadOnly="True"
    HorizontalAlignment="Stretch"
    ItemsSource="{Binding ...}"
    IsDropDownOpen="{Binding Path=DropOpen, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, UpdateSourceTrigger=PropertyChanged}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Eintrag}" HorizontalContentAlignment="Stretch" Checked="CheckBox_Checked_Unchecked" Unchecked="CheckBox_Checked_Unchecked"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

CodeBehind:

    private string combotextfilter = "<No Selection>";

    public string ComboTextFilter
    {
        get { return combotextfilter; }
        set
        {
            if (value != null && value.IndexOf("ComboModel") != -1) return;
            combotextfilter = value;
            NotifyPropertyChanged(nameof(ComboTextFilter));
        }
    }

    private void CheckBox_Checked_Unchecked(object sender, RoutedEventArgs e)
    {
        switch (((ObservableCollection<ComboModel>)combobox.ItemsSource).Count(x => x.IsChecked))
        {
            case 0:
                ComboTextFilter = "<No Selection>";
                break;
            case 1:
                ComboTextFilter = ((ObservableCollection<ComboModel>)combobox.ItemsSource).Where(x => x.IsChecked).First().Eintrag;
                break;
            default:
                ComboTextFilter = ((ObservableCollection<ComboModel>)combobox.ItemsSource).Where(x => x.IsChecked).Select(x => x.Eintrag).Aggregate((i, j) => i + " | " + j);
                //ComboTextFilter = "<Multiple Selected>";
                break;
        }

        NotifyPropertyChanged(nameof(C_Foreground));
    }

    public bool DropOpen
    {
        get { return dropopen; }
        set { dropopen = value; NotifyPropertyChanged(nameof(ComboTextFilter)); }
    }
    private bool dropopen = false;

Solution 2:[2]

@Xaviers answer works 99% of the way. However the user is able to accidently select a checkbox and then the ToString() of the checkbox is shown as the selected text. This can happen quite alot actually. I havent yet worked out why this happens, but I've found a way to prevent this.

Create a bool property that binds to the DropDownOpen property of the combobox and when the DropDownOpen has changed to false it means that the DropDown has just been closed and you might be facing the above problem. So here you just raise the propertychanged event for the viewmodel and pass the property bound to the Text property of the combobox.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris
Solution 2 Erik83