36

My google skills fail me. Anyone heard of a control like that for WPF. I am trying to make it look like this (winforms screenshot).

Pyritie
  • 543
  • 4
  • 16
AngryHacker
  • 59,598
  • 102
  • 325
  • 594

4 Answers4

63

You can do this yourself by setting the DataTemplate of the combo box. This article shows you how - for a listbox, but the principle is the same.


Another article here is perhaps a better fit for what you are trying to do, simple set the first column of the item template to be a checkbox and bind it to a bool on your business object.

<ComboBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding IsSelected}"
                       Width="20" />
            <TextBlock Text="{Binding DayOfWeek}"
                       Width="100" />
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>
Martin Harris
  • 28,277
  • 7
  • 90
  • 101
23

There is my combobox. I use Martin Harris code and code from this link Can a WPF ComboBox display alternative text when its selection is null?

<ComboBox Name="cbObjects" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="2,2,6,0" SelectionChanged="OnCbObjectsSelectionChanged" >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsSelected}" Width="20" VerticalAlignment="Center" Checked="OnCbObjectCheckBoxChecked" Unchecked="OnCbObjectCheckBoxChecked" />
                <TextBlock Text="{Binding ObjectData}" VerticalAlignment="Center" />
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
<TextBlock IsHitTestVisible="False" Name="tbObjects" Text="Выберите объекты..." Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="6,2,6,0" />

Small class for datasource:

public class SelectableObject <T> {
    public bool IsSelected { get; set; }
    public T ObjectData { get; set; }

    public SelectableObject(T objectData) {
        ObjectData = objectData;
    }

    public SelectableObject(T objectData, bool isSelected) {
        IsSelected = isSelected;
        ObjectData = objectData;
    }
}

And there is two handler - one for handling CheckBox clicked and one for forming Text for ComboBox.

private void OnCbObjectCheckBoxChecked(object sender, RoutedEventArgs e) {
    StringBuilder sb = new StringBuilder();
    foreach (SelectableObject<tblObject> cbObject in cbObjects.Items) 
    {
        if (cbObject.IsSelected)
            sb.AppendFormat("{0}, ", cbObject.ObjectData.Description);
    }
    tbObjects.Text = sb.ToString().Trim().TrimEnd(',');
}

private void OnCbObjectsSelectionChanged(object sender, SelectionChangedEventArgs e) {
    ComboBox comboBox = (ComboBox)sender;
    comboBox.SelectedItem = null;
}

For ComboBox.ItemsSource I use

ObservableCollection<SelectableObject<tblObject>> 

where tblObject is type of my object, a list of which I want to display in ComboBox.

I hope this code is useful to someone!

Pyritie
  • 543
  • 4
  • 16
Sergey
  • 1,837
  • 1
  • 18
  • 22
  • I liked the idea of SelectableObject. +1! – Ignacio Soler Garcia Jun 22 '12 at 16:12
  • 3
    imho StackPanel and TextBlock in template are redundant, could just bind Content property of checkbox to ObjectData.. – Taras Mar 05 '17 at 19:01
  • This solution works remarkably well despite being a bit kludgey (it requires two different, stacked controls). The accepted answer only gets you started and is incomplete. Other solutions involve modifying the ComboBox's template or creating custom controls and are far more complex. – OfficeAddinDev Jul 14 '19 at 10:37
  • Please Explain How to add value in ObservableCollection> as generic . – Harmi Jan 31 '20 at 14:29
  • If you're binding any property of your object then the binding expression must be `{Binding ObjectData.PropertyName}` – Nilesh Thakkar May 13 '21 at 11:22
11

Give a try to CheckComboBox from Extended WPF Toolkit. The main advantage for me is having two lists for binding:

  • all items available for selection
  • just selected items

I find this approach more practical. In addition you can specify value and display members of the collections you're binding.

If you don't want to bring a bunch of other controls with CheckComboBox, you can get the source code of it, it's pretty straightforward (need to bring Selector class as well).

Goigle
  • 138
  • 13
Alex Klaus
  • 8,168
  • 8
  • 71
  • 87
6

ComboBox with Checkboxes

<ComboBox Height="16" Width="15">
    <CheckBox Content="First Checkbox" />
    <CheckBox Content="Second Checkbox" />
    <CheckBox Content="Third Checkbox" />
    <TextBlock Text="Some Text" />
</ComboBox>

The provided answers surprisingly didn't work for me, I tried many variations and kept getting error messages about the checkbox not being part of combobox and the data context seemed to be broken.

In the end I didn't have to do anything involving data templates or any code behind and my bindings are working fine (not shown in example)

ComboBox with Checkboxes

I must say I'm happy with how easy this turned out to be after reading all the answers.