WPF: ComboBox with CheckBoxes as items (it will even update on the fly!)

January 19, 2009

tags: ,
91 comments

Hi,

 

Recently I’ve come across something weird… I needed a ComboBox that will allow the user to select multiple items.
The the solution coming to mind is using CheckBoxes. I have found several examples, but neither one displayed the selected items with pretty commas (like this: image ).

 

I’ve decided the best solution willl be taking an example from MSDN and modifying it to suite my needs.

Steps: (actually took ALOT longer and was ALOT harder – learning curves and such)

  1. Created a UserControl.
  2. Added the ComboBox from the MSDN sample.
  3. Created 3 dependency properties:
    • Text – retrieves the text of the selected items
    • ItemsSource – the items to display (currently bound to Title and IsSelected)
    • DefaultText – the text to display if no items were checked
  4. Bound the ItemsSource properties of the UserControl and the ComboBox.
  5. Added a Click event to the CheckBox that refreshes the text field in the ContentPresenter.

Usage

<Window





xmlns:controls="clr-namespace:Controls;assembly=Controls"

<controls:ComboWithCheckboxes
    x:Name="cbLanguages"
    Height="22"
    DefaultText="Choose Subtitles..."
    ItemsSource="{Binding}"
    />

 

Result

image

image

image

Code

 

ComboWithCheckboxes.xaml

<UserControl x:Class="Controls.ComboWithCheckboxes"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="22" Width="120"
    x:Name="UserControl"
    >
    
    <UserControl.Resources>
        <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FFF" Offset="0.0"/>
                    <GradientStop Color="#CCC" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#CCC" Offset="0.0"/>
                    <GradientStop Color="#444" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <SolidColorBrush x:Key="GlyphBrush" Color="#444" />

        <LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FFF" Offset="0.0"/>
                    <GradientStop Color="#AAA" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#BBB" Offset="0.0"/>
                    <GradientStop Color="#EEE" Offset="0.1"/>
                    <GradientStop Color="#EEE" Offset="0.9"/>
                    <GradientStop Color="#FFF" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

        <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />

        <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />

        <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />

        <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="20" />
                </Grid.ColumnDefinitions>
                <Border
                  x:Name="Border" 
                  Grid.ColumnSpan="2"
                  CornerRadius="2"
                  Background="{StaticResource NormalBrush}"
                  BorderBrush="{StaticResource NormalBorderBrush}"
                  BorderThickness="1" />
                <Border 
                  Grid.Column="0"
                  CornerRadius="2,0,0,2" 
                  Margin="1" 
                  Background="{StaticResource WindowBackgroundBrush}" 
                  BorderBrush="{StaticResource NormalBorderBrush}"
                  BorderThickness="0,0,1,0" />
                <Path 
                  x:Name="Arrow"
                  Grid.Column="1"     
                  Fill="{StaticResource GlyphBrush}"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center"
                  Data="M 0 0 L 4 4 L 8 0 Z"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="ToggleButton.IsMouseOver" Value="true">
                    <Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" />
                </Trigger>
                <Trigger Property="ToggleButton.IsChecked" Value="true">
                    <Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" />
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
                    <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
                    <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        
        <ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
            <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
        </ControlTemplate>

        <Style x:Key="{x:Type ComboBoxItem}" TargetType="ComboBoxItem">
            <Setter Property="SnapsToDevicePixels" Value="true"/>
            <Setter Property="OverridesDefaultStyle" Value="true"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ComboBoxItem">
                        <Border 
                          Name="Border"
                          Padding="2"
                          SnapsToDevicePixels="true">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsHighlighted" Value="true">
                                <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <ComboBox
        x:Name="CheckableCombo"
        SnapsToDevicePixels="True"
        OverridesDefaultStyle="True"
        ScrollViewer.HorizontalScrollBarVisibility="Auto"
        ScrollViewer.VerticalScrollBarVisibility="Auto"
        ScrollViewer.CanContentScroll="True"
        IsSynchronizedWithCurrentItem="True"
        MinWidth="120"
        MinHeight="20"
        ItemsSource="{Binding ElementName=UserControl, Path=ItemsSource}"
        DataContext="{Binding ElementName=UserControl, Path=DataContext}"
        >
        <ComboBox.ItemTemplate>
            <HierarchicalDataTemplate>
                <CheckBox Content="{Binding Title}"
                          IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"
                          Tag="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}"
                          Click="CheckBox_Click"
                          />
            </HierarchicalDataTemplate>
        </ComboBox.ItemTemplate>

        <ComboBox.Template>
            <ControlTemplate TargetType="ComboBox">
                <Grid>
                    <ToggleButton 
                        Name="ToggleButton" 
                        Template="{StaticResource ComboBoxToggleButton}" 
                        Grid.Column="2" 
                        Focusable="false"
                        IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                        ClickMode="Press">
                    </ToggleButton>
                    <ContentPresenter
                        x:Name="Presenter"
                        IsHitTestVisible="False" 
                        Margin="3,3,23,3"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Left">
                        <ContentPresenter.Content>
                            <TextBlock TextTrimming="CharacterEllipsis"
                                       Text="{Binding Path=Text,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
                        </ContentPresenter.Content>
                    </ContentPresenter>
                    <!-- Content="{TemplateBinding SelectionBoxItem}" -->
                    <TextBox x:Name="EditableTextBox"
                        Style="{x:Null}" 
                        Template="{StaticResource ComboBoxTextBox}" 
                        HorizontalAlignment="Left" 
                        VerticalAlignment="Center" 
                        Margin="3,3,23,3"
                        Focusable="True" 
                        Background="Transparent"
                        Visibility="Hidden"
                        IsReadOnly="{TemplateBinding IsReadOnly}"/>
                    <Popup 
                        Name="Popup"
                        Placement="Bottom"
                        IsOpen="{TemplateBinding IsDropDownOpen}"
                        AllowsTransparency="True" 
                        Focusable="False"
                        PopupAnimation="Slide">
                        <Grid 
                                  Name="DropDown"
                                  SnapsToDevicePixels="True"                
                                  MinWidth="{TemplateBinding ActualWidth}"
                                  MaxHeight="{TemplateBinding MaxDropDownHeight}">
                            <Border 
                                    x:Name="DropDownBorder"
                                    Background="{StaticResource WindowBackgroundBrush}"
                                    BorderThickness="1"
                                    BorderBrush="{StaticResource SolidBorderBrush}"/>
                            <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True" DataContext="{Binding}">
                                <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                            </ScrollViewer>
                        </Grid>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                    <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
                    </Trigger>
                    <Trigger Property="IsEditable"
                   Value="true">
                        <Setter Property="IsTabStop" Value="false"/>
                        <Setter TargetName="EditableTextBox" Property="Visibility"    Value="Visible"/>
                        <Setter TargetName="Presenter" Property="Visibility" Value="Hidden"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </ComboBox.Template>
    </ComboBox>
</UserControl>

 

ComboWithCheckboxes.xaml.cs

usingSystem.Windows;

namespace Controls

{

    /// <summary>

    ///
Interaction logic for ComboWithCheckboxes.xaml

  
/// </summary>

  
public partial classComboWithCheckboxes

  
{

        #regionDependency Properties

        /// <summary>

        ///
Gets or sets a collection used to generate the content of the ComboBox

      
/// </summary>

      
public objectItemsSource

        {

            get{ return(object)GetValue(ItemsSourceProperty); }

            set

          
{

                SetValue(ItemsSourceProperty, value);

                SetText();

            }

        }

        public static readonlyDependencyPropertyItemsSourceProperty =

            DependencyProperty.Register("ItemsSource", typeof(object), typeof(ComboWithCheckboxes), newUIPropertyMetadata(null));

        /// <summary>

        ///
Gets or sets the text displayed in the ComboBox

      
/// </summary>

      
public stringText

        {

            get{ return(string)GetValue(TextProperty); }

            set{ SetValue(TextProperty, value); }

        }

        public static readonlyDependencyPropertyTextProperty =

            DependencyProperty.Register("Text", typeof(string), typeof(ComboWithCheckboxes), newUIPropertyMetadata(string.Empty));

        /// <summary>

        ///
Gets or sets the text displayed in the ComboBox if there are no selected items

      
/// </summary>

      
public stringDefaultText

        {

            get{ return(string)GetValue(DefaultTextProperty); }

            set{ SetValue(DefaultTextProperty, value); }

        }

        // Using a DependencyProperty as the backing store for DefaultText.  This enables animation, styling, binding, etc…

      
public static readonlyDependencyPropertyDefaultTextProperty =

            DependencyProperty.Register("DefaultText", typeof(string), typeof(ComboWithCheckboxes), newUIPropertyMetadata(string.Empty));

        #endregion

        publicComboWithCheckboxes()

        {

            InitializeComponent();

        }

        /// <summary>

        ///
Whenever a CheckBox is checked, change the text displayed

      
/// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

       private voidCheckBox_Click(objectsender, RoutedEventArgse)

        {

            SetText();

        }

        /// <summary>

        ///
Set the text property of this control (bound to the ContentPresenter of the ComboBox)

      
/// </summary>

      
private voidSetText()

        {

            this.Text = (this.ItemsSource != null) ?

                this.ItemsSource.ToString() : this.DefaultText;

            // set DefaultText if nothing else selected

          
if(string.IsNullOrEmpty(this.Text))

            {

                this.Text = this.DefaultText;

            }

        }

    }

}

That’s it!

Adi.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

91 comments

  1. Masoom Ali March 11, 2009 ב 08:44

    hi.. that was good article please send me the control on from to email address “im.masoomali@gmail.com”

    Reply
  2. MarMarch 16, 2009 ב 10:46

    Hi. This article is great, i need to do the exact same thing. Could you please send me the control via email or upload it here? I tried to modify the code in here, but i´m new at this and i have errors that i don´t know how to correct.
    Help me please!!

    My email address is: mmgv5@yahoo.com

    Thanks!!

    Reply
  3. Gajender PalApril 10, 2009 ב 20:01

    what ItemSource i can provide to this control?

    Reply
  4. Rob LewisApril 23, 2009 ב 22:59

    Adi, this is so good it’s not even funny. Thank you!!

    Gajender – This worked for me:

    public class Node
    {
    public Node(string n) { Title = n; }
    public string Title { get; set; }
    public bool IsSelected { get; set; }
    }

    public class ObservableNodeList : ObservableCollection
    {
    public ObservableNodeList()
    {
    }

    public override string ToString()
    {
    StringBuilder outString = new StringBuilder();
    foreach (Node s in this.Items)
    {
    if (s.IsSelected == true)
    {
    outString.Append(s.Title);
    outString.Append(‘,’);
    }
    }

    return outString.ToString().TrimEnd(new char[] {‘,’});
    }
    }

    Reply
  5. Gavin McKayApril 24, 2009 ב 01:52

    Fantastic work Adi, this is an extremely useful control! Just solved my multi-selection headache.

    Rob – side note, the using statements required for your nodelist are:

    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Text;

    I got compile errors because I was missing .ObjectModel.

    Reply
  6. justguyMay 20, 2009 ב 06:08

    Hi, guys,

    Sorry for the late response. The web’s been keeping me busy…

    Glad to see someone found a use for this control.

    I hope Gavin’s comment helped with the errors.

    Reply
  7. Amy PhamJune 1, 2009 ב 17:56

    This is great! You saved me ;-) I liked this post so much that I revisited other posts discussing about multiselect combobox to come to this post. Thank you, thank you Adi!

    Reply
  8. AmyJune 2, 2009 ב 18:15

    Thank you for posting this code Adi. Would you please give some ideas on how to use this multiselect combobox in a datagrid? My users want to have multiselect columns in a datagrid.

    Thanks,
    Amy

    Reply
  9. SidJune 10, 2009 ב 01:19

    Thx for the code. However that does not work for me:

    1) I imported the code in a separate project and referenced from my VB.Net project.
    2) I created a class that contains checkboxes data (the Node class of the Rob Lewis comment)
    3) Then I created a collection with an overrided ToString method to contain the nodes collection.
    4) Setting the ItemsSource to that populated collection binds everything well, but the data:

    The dropdown will populate the popup and show the text (“Checkbox A, Checkbox B, …”).
    The popup will show the correct number of checkboxes, but will not bind to the Node class: checkboxes will not be checked and the Text property will not be set. Neither the object>source binding will work: checking the checkbox will not change the IsSelected property of my Node.

    Yes, the Node class has IsSelected and Title fields.

    May you post or send an example?
    E-Mail: alberto AT alvy DOT tv

    Thx in advance!

    Reply
  10. marengJune 11, 2009 ב 13:00

    Great code!

    I use it in a wpf toolkit datagrid, and it almost works perfectly. But when a row is selected, the usercontrol dosen´t display the default text or if any values is selected, them as a comma seperated string, it displays nothing, otherwise it works fine.

    Any suggestions?

    Thanks in advance!

    Reply
  11. justguyJune 14, 2009 ב 08:53

    Hi, Alberto,

    I’m sorry, but my laptop dropped dead, and I don’t have an example to provide.

    Can anyone else help?

    Reply
  12. ronKJune 30, 2009 ב 12:01

    Great example thought this is not working for me and I can’t understand why.
    I have copied the user control with the .cs, and created the node and the collection classes.
    I populate the item source in the code behind :
    (the button.YParametersFieldNames holds the previously selected parameters)

    ObservableNodeList itemSource = new ObservableNodeList();

    List selectedParameters = new List(button.YParametersFieldNames);
    foreach (DataColumn column in button.DataSource.Columns)
    {
    Node item = new Node(column.Caption);
    item.IsSelected = selectedParameters.Contains(item.Title);
    itemSource.Add(item);
    }
    comboYParameters.ItemsSource = itemSource;

    and the result if the comboBox looks empty with no available items to select from.
    what am I missing here ?

    Reply
  13. ronKJune 30, 2009 ב 15:38

    forget my last comment, found the erorr – I accidently removed the x:name of the user control which made the binding of the item source to not work correctly.

    Reply
  14. smithaJune 30, 2009 ב 22:56

    Hi,
    can you please post the code that goes in window.xaml.cs ,I am a newbie trying to use usercontrols and i am unable to get your code working,

    Thanks you so much

    Reply
  15. SmithaJune 30, 2009 ב 23:00

    Hi all,
    those who got it to work.
    can you plesae see what is wrong in my code.
    This is how my window.xaml.cs looks.Rest of teh code is directly from the code above.I cannot get the checkboxes to display.

    public partial class Window1 : Window
    {
    public Window1()
    {
    InitializeComponent();

    ObservableNodeList itemSource = new ObservableNodeList();

    itemSource.Add(new Node(“Willa”));

    itemSource.Add(new Node(“Isak”));
    itemSource.Add(new Node(“Victor”));
    itemSource.Add(new Node(“Jules”));

    cbLanguages.ItemsSource = itemSource;
    cbLanguages.DataContext = itemSource;

    // listBox1.ItemsSource = itemSource;
    }
    }
    public class Node
    {

    public Node(string n) { Title = n; }

    public string Title { get; set; }

    public bool IsSelected { get; set; }

    }

    public class ObservableNodeList : ObservableCollection
    {

    public ObservableNodeList()
    {

    }

    public override string ToString()
    {

    StringBuilder outString = new StringBuilder();

    foreach (Node s in this.Items)
    {

    if (s.IsSelected == true)
    {

    outString.Append(s.Title);

    outString.Append(‘,’);

    }

    }

    return outString.ToString().TrimEnd(new char[] { ‘,’ });

    }

    }
    }

    Reply
  16. SmithaJune 30, 2009 ב 23:09

    Cant see my two posts

    Reply
  17. RangaJuly 7, 2009 ב 14:33

    Can you please provide, proper sample.

    Reply
  18. RangaJuly 7, 2009 ב 16:24

    Steps to make it work:
    1. Update the property “ItemsSource” in ComboWithCheckboxes class with the following code.
    public object ItemsSource
    {
    get { return (object)GetValue(ItemsSourceProperty); }
    set
    {
    this.CheckableCombo.ItemsSource = (System.Collections.IEnumerable)value;
    SetValue(ItemsSourceProperty, value);
    SetText();
    }
    }
    2. Add the following code in the window1.xaml.cs
    ObservableNodeList itemSource = new ObservableNodeList();
    Node a = new Node(“Dog”);
    a.IsSelected = true;

    itemSource.Add(a);

    Node b = new Node(“Monkey”);
    b.IsSelected = false;
    itemSource.Add(b);

    cbLanguages.ItemsSource = itemSource;

    Reply
  19. MaxSeptember 18, 2009 ב 12:21

    Hi, thank you for the control.
    But I can’t find the DisabledBorderBrush resource… can you add it or point to the location?

    Reply
  20. KKNovember 4, 2009 ב 17:03

    Hi Folks,

    Can anyone of you who got it to work can please email me the usercontrol.

    Will appreciate it. Thanks a lot!!!

    my email id is mkkeerthi@rediffmail.com

    Reply
  21. steven hawkesNovember 16, 2009 ב 14:08

    I am having a problem getting the ItemSource events to fire.

    For example, I databind the ItemsSource property to an ObservableNodeList as a public property. However, when I write my data into this property, the data is written into the ItemsSource and is available in the drop down but the SetText is not called so the selected items in the list are not updated in the ComboBox view when collapsed.

    If I subsequently open the combopox and deselect an item , then the combobox refreshes from the ButtonClick event.

    I checked and for some reason the Set and Get methods are not being called at all when I assign to the ItemSource property.

    any ideas what I could be doing wrong?

    Reply
  22. VladimirJanuary 16, 2010 ב 16:03

    Hello,

    Great control, I like it. But I’ve got some problems with stretching it horizontally. It doesn’t behave like usual combobox – setting HorizontalAlignment isn’t enough for stretching it. Removing Width=”120″ setting of UserControl also dodn’t help me. Could somebody help me?

    The task is to show this control stretched horizontally.

    Reply
  23. VladimirJanuary 16, 2010 ב 16:50

    Never mind, please. The problem was in code around the control, not in control itself.

    Reply
  24. RetoJanuary 18, 2010 ב 18:55

    Is it possible to download the latest version of the control from somewhere? Or could somebody mail me this to
    “rgb64(at)bluemail.ch”

    Thanks

    Reply
  25. Mikael MadsenJanuary 25, 2010 ב 10:44

    Hey there. I’m having some problems with GetValue and setValue in the codebehind file. can anyone tell me how to correct these errors or maybe send a working sourcefile to me at:
    Mikael_Madkasse@Hotmail.com

    kthxbye

    Reply
  26. Bahri GungorJanuary 29, 2010 ב 21:21

    You can resolve the GetValue/SetValue compile errors by deriving the control (in the codebehind) from UserControl.

    public partial class ComboWithCheckboxes : UserControl

    Reply
  27. Satyam KumarFebruary 10, 2010 ב 20:10

    Hi Adi,

    It is really a beautifull code. Can you please send me the code to me subham11@gmail.com

    Thanks & Regards,

    Satyam Kumar.

    Reply
  28. JoeMarch 4, 2010 ב 22:30

    You can use generics to make multi-select entity collections easier:

    1) Create interface “ISelectable”:
    public interface ISelectable
    {
    bool IsSelected { get; set; }
    string DisplayName { get; }
    }

    2) Implement ISelectable on entity:
    public partial MyEntity : ISelectable
    {
    public bool IsSelected { get; set; }
    public string DisplayName {
    get { return this.PropertyToDisplay; }
    }
    }

    3) Create MultiSelectEntityCollection:
    public class MultiSelectEntityCollection

    : ObservableCollection

    where T : ISelectable
    {
    public override string ToString()
    {
    var str = new StringBuilder();
    Items.ToList().ForEach( item =>
    {
    if ( item.IsSelected )
    {
    str.Append( item.DisplayName );
    str.Append( “, ” );
    }
    } );

    return str.ToString().TrimEnd( ‘,’ );
    }
    }

    4) Use MultiSelectEntityCollection in your code:

    public MultiSelectEntityCollection MyMultiSelectableEntityCollection { get; set; }

    Cheers,
    refereejoe at yahoo dot com

    Reply
  29. kingMarch 22, 2010 ב 13:42

    Implementing this user control in MVVM pattern, itemsource doesn’t change when we change this from code

    Reply
  30. frankMarch 25, 2010 ב 10:35

    ItemsSource doesn’t work initially in a Datagrid (wpftoolkit).

    This is a workaround. In the grid:





    The Converter:
    [ValueConversion(typeof(object), typeof(string))]
    public class InitialTextConverter : IValueConverter
    {
    public object Convert(object value, Type targetType,
    object parameter, System.Globalization.CultureInfo culture)
    {
    if (value is ObservableNodeList)
    {
    ObservableNodeList list = (ObservableNodeList)value;
    if (list.AllChecked())
    return “All”;
    if (list.NoneChecked())
    return “None”;
    return list.ToString();
    }
    return string.Empty;
    }

    public object ConvertBack(object value, Type targetType,
    object parameter, System.Globalization.CultureInfo culture)
    {
    // we don’t intend this to ever be called
    return null;
    }
    }

    I also had to change the content of the default Combobox (as the text was not visible sometimes):

    Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
    Text="{Binding Path=Text,Mode=OneWay,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}">

    Reply
  31. guruvnMay 7, 2010 ב 13:57

    So far so good, I have tried to figure out how to get it done via using xaml only, but sound seems to be we have to handle it on both xaml & code behind

    Reply
  32. AndreasJuly 9, 2010 ב 18:47

    This example works great! Thanks for that!
    There is only a small “bug” I have with the xaml:
    When I select some items, sometimes I click “between” two items (meaning: somewhere in the top or bottom of an item). The instead of selecting this item, the selection box disappears. Does anyone have a solution for that?

    Reply
  33. Debasish dasJuly 16, 2010 ב 10:31

    Please send me the wpf control in mailid as soon as possible.
    my mail id:-
    debasish.das04@gmail.com

    Reply
  34. Debasish dasJuly 16, 2010 ב 14:58

    Please send me the control with code…my mail id:- debasish.das04@gmail.com

    Reply
  35. AndreasJuly 30, 2010 ב 11:54

    If found a solution to the follwing issuee posted a little bit earlier by me:

    The problem was when I selected some items, sometimes when clicking “between” two items (meaning: somewhere in the top or bottom of an item), instead of selecting this item the selection box was closed. Apparently the check box did not register the click, and somehow the event was registered as clicking outside of the popup.

    There is an easy way to solve the problem: Set the margin of the checkbox in the to negative values!

    So, e.g. Margin=”0,-5,0,-5″ added to the checkbox tag would resolve the issue.

    Reply
  36. PriteshAugust 2, 2010 ב 11:21

    Hi.

    Just went through your code.

    It is the same type of control I wanted to implemented.

    But somehow the code is not working.

    Can you please share the sourcecode once again?

    Reply
  37. Guru sAugust 8, 2010 ב 00:43

    I am able to fix the code and make it run. I want to using this control in MVVM model. I am not able to get the selected checkbox value. Does any one tryit. If yes please post the code.

    Thanks,

    Reply
  38. PradSeptember 10, 2010 ב 16:28

    How can I add
    1. tooltip (TextBox) and
    2. quick search (like on key press of D should highlight items starting with D)

    to the above example?

    Reply
  39. PradSeptember 10, 2010 ב 23:03

    I have been trying to clear all the checkbox for a button Clear All.

    The TextProperty works but the checkbox are still in check state although ObservabelNodeList shows isSelected = false.

    private void button1_Click(object sender, RoutedEventArgs e)
    {
    foreach (Node n in (ObservableNodeList)comboCheckBox1.ItemsSource)
    {
    if (n.IsSelected) n.IsSelected = false;
    }
    }

    Reply
  40. venkatOctober 6, 2010 ב 21:04

    Hi I like your solution, can you email me the complete solution. My email is venkatap@gmail.com

    Reply
  41. Amy TusunOctober 11, 2010 ב 04:52

    Hi, I will be able to use your solution in my project if I can make the control editable (i.e. user can type as well as check boxes). In other words I need IsEditable property to be true. I tried to add this property but it didn’t work.

    Reply
  42. VilasNovember 6, 2010 ב 23:39

    Solution looks elegant. Can you please email me the solution at vilash001@yahoo.com. Thanks again

    Reply
  43. soonNovember 9, 2010 ב 11:55

    Can you please email me the solution at cpjack@yahoo.cn. Thanks again

    Reply
  44. sandeepNovember 11, 2010 ב 05:34

    This is what i wanted. Other 3rd party ones doesn’t work for my scenarios. Please email me the solution at deshmukhsandeep023@gmail.com.

    Reply
  45. GabeNovember 12, 2010 ב 12:56

    I want to implement it, but a lot of errors appeared.
    So, can someone send me the source codes? Please help me.
    Thanks.

    Reply
  46. minhoNovember 29, 2010 ב 08:55

    Please send me the control with code…my mail id: sexyminho@hotmail.com

    Reply
  47. mochyDecember 10, 2010 ב 15:29

    Hey,

    Just wanted to say thank you. I got it working easily, this solution is perfect for my application.

    I implemented it using MVVM pattern and I am having an issue when switching tabs, the Text property becomes empty again, even tough things are checked in the list… have to figure this out!

    Thanks again!

    Reply
  48. MatthewMarch 2, 2011 ב 16:12

    Nice, but my problem with this is that if you click *between* an item while the box is dropped-down, the box closes. This, to me, renders the control unusable. Is there any way to prevent this?

    Reply
  49. MorganMarch 2, 2011 ב 18:54

    Getting this error in my project

    System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=IsDropDownOpen; DataItem=’ComboBox’ (Name=’CheckableCombo’); target element is ‘ToggleButton’ (Name=’ToggleButton’); target property is ‘IsChecked’ (type ‘Nullable`1′) XamlParseException:’System.Windows.Markup.XamlParseException: Provide value on ‘System.Windows.Markup.StaticResourceHolder’ threw an exception. —> System.Exception: Cannot find resource named ‘ValidationToolTipTemplate’. Resource names are case sensitive.
    at System.Windows.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider

    I do indeed have the template resource and it is in my project. Not sure where else to find help for this… It errors out with a Object not set to an instance..

    Reply
  50. sunnycMarch 16, 2011 ב 11:33

    Would u please send a example for me?
    sunny29301@163.com,I have some problem with the data binding,It shows nothing.Thank u very much

    Reply
  51. RyanMarch 25, 2011 ב 13:39

    Please send me the code mrachek@gmail.com

    Reply
  52. KenMarch 30, 2011 ב 18:21

    To fix the problem Andreas and Mathew talk about remove the Padding=2 from the Border in the ComboBoxItem Style

    Reply
  53. MatthewApril 1, 2011 ב 19:32

    Thanks for providing the “Padding=2″ removal suggestion, and while it does indeed work, it jams the checkboxes up so that there’s no space between them! It’s a great control, but shame I’m still a WPF newbie and am not able to solve things such as this for myself!

    Reply
  54. SameerApril 19, 2011 ב 11:19

    Hi Adi, Can u plz send me the code of above control. i am in need of the same. plz help me……………..

    Reply
  55. RoshilMay 9, 2011 ב 16:45

    Pls send me the code.
    roshilk@gmail.com

    Reply
  56. GunnarMay 13, 2011 ב 01:02

    Hi Adi,
    Code works a charm after a bit of fiddling.
    Most appreciated. Saved me some time and learned interesting stuff.
    Thanks mate.

    Reply
  57. Ankur JunejaMay 13, 2011 ב 21:35

    am in urgent need of this control. please send me at the given email id. please help me out guys….

    ankur_juneja2004@yahoo.co.in

    Reply
  58. SivaJune 8, 2011 ב 14:39

    Hi mochy,

    I am facing an problem in binding the ItemsSource using the Binding Path. The item source does not bind by using MVVM. When i bind directly in code behind it is working perfectly.

    I tried by setting by the binding using the Dependency property but did not work as well.

    You have mentioned that you were able to achive this control in MVVM. Can you please send me the complete solution to sivasankar.s4u@gmail.com

    Thanks,
    Siva

    Reply
  59. SekharJuly 5, 2011 ב 15:36

    where could i get this code sample.

    Reply
  60. PraveenJuly 7, 2011 ב 13:45

    Plz Send source code of this article. Thanks

    Reply
  61. gurpreetJuly 8, 2011 ב 08:36

    can you please help me how to implement combobox with checkbox in windows form application(c sharp)……gurpreetsingh225@hotmail.com

    Reply
  62. KhyatiJuly 18, 2011 ב 00:32

    If anyone knows how to implement this control in datagrid. Please share your code to khyati.shah@yahoo.co.in.

    Reply
  63. sivakumarJuly 22, 2011 ב 11:20

    hi this is nice artical , but i dont have that much knowledge to understand , please explain me the full atrical particularlly and send this to my mail address sivakumarmr10@gmail.com , thankq very much

    Reply
  64. stukselbaxAugust 9, 2011 ב 13:28

    Why do you use HierarchicalDataTemplate instead of just DataTemplate?

    Reply
  65. siva kumarAugust 13, 2011 ב 09:37

    i had used the Usercontrol but iam getting This Error So please Rectify this error

    error:
    Provide value on ‘System.Windows.Markup.StaticResourceHolder’ threw an exception.

    Reply
  66. syntaxAugust 19, 2011 ב 00:21

    Is there anyway I can uncheck all the checked items programatically?? I tried change in datasource (itemsource) but it didnt work out. What will be the best way to reinitilize these combos??

    Reply
  67. NirAugust 21, 2011 ב 22:45

    Great solution. Can you mail me the control code at nirnirkal@yahoo.com

    Reply
  68. DayanandOctober 25, 2011 ב 11:05

    Great work buddy…but i’m find it hard to implement…i would appreciate if you could mail the solution on my email ID : dkale86@gmail.com

    Reply
  69. NishanthNovember 10, 2011 ב 11:11

    Can you please mail the solution at nishanth2@gmail.com? Thanks in advance.

    Reply
  70. Rohit AroraDecember 2, 2011 ב 11:18

    please mail solution to me at
    rohit.arora@irissoftware.com

    Thanks

    Reply
  71. Ramakrishna BarikiJanuary 1, 2012 ב 07:56

    I need a solutions hard to implement please mail

    me : ramakrishna.bariki@gmail.com

    Reply
  72. ChandanFebruary 3, 2012 ב 05:02

    this is excellent!! Great work!

    Reply
  73. pbFebruary 8, 2012 ב 21:13

    can someone please mail the source to me at bhardwaj.cs@gmail.com

    Reply
  74. itdevFebruary 23, 2012 ב 17:13

    Great!
    Can someone please mail the source code or better a small working project to me at hb.itdev@gmail.com
    I’m not able to use the control without error at runtime

    Reply
  75. VenkatFebruary 27, 2012 ב 13:42

    Hi

    This is a great article and useful to me.But i need some more events.I have two groups of checkboxes country and state.When i select one checkbox in country combo then the relevant states of the country should appear in state combo.I am not able to fire any event which will refresh the state combo.Can someone help me to resolve the issue. It will be a great pleasure if you could send the solution to my mail urvenkatg@gmail.com

    Thanks in advance
    Venkat

    Reply
  76. onuralp tanerMarch 3, 2012 ב 23:34

    Please, post or send me an example?

    E-Mail: onuralp at hotmail DOT com

    Best Regards

    Reply
  77. Lazaro CastañoMarch 13, 2012 ב 22:07

    Genial code…..thanks a lot…

    Reply
  78. ShaktiMarch 16, 2012 ב 08:01

    Some of the brushes used as StaticResource in the user control in the xaml file are missing. It would be great if you can add it.

    Reply
  79. sunnyApril 3, 2012 ב 12:04

    I am getting

    Visual Studio designer gave an error dialog “Provide value on ‘System.Windows.Markup.StaticResourceHolder’ threw an exception.”

    when i try to use control in wpf form

    Reply
  80. AlexApril 12, 2012 ב 16:44

    Great work buddy…but i’m find it hard to implement…i would appreciate if you could mail the solution on my email ID : jjalexrayer@yahoo.com

    Reply
  81. cjwAugust 24, 2012 ב 05:25

    I try to get it work but seem to be not working well. Can some send me the code on my email: cjwiphone@hotmail.com. Thank you very much.

    Reply
  82. prathiAugust 30, 2012 ב 14:30

    Hi its workling fine. but when i select a item and click directly on button results are not obtained as combo box requires a click event after the selection.

    any suggestion about this.

    thank u

    Reply
  83. KenSeptember 5, 2012 ב 02:50

    Remove the SolidBorderBrush in the xaml and it will remove the error
    System.Windows.Markup.StaticResourceHolder’ threw an exception

    Reply
  84. ValentinoNovember 22, 2012 ב 15:03

    Good work! Can you mail me the control code and a working sample: at valefior AT inwind DOT it?

    Thanks

    Reply
  85. Abdul SamadDecember 22, 2012 ב 16:30

    I am using MS VS 2010. I have create component as you described on the top and created it in C#.

    Now i want to use the component in VB.NET but it say ‘Object reference not set to an instance of object’

    Please advise

    Would you please upload ZIP file with latest c# code, which i can use in VB.NET?

    Reply
  86. GowthamMarch 12, 2013 ב 10:14

    Great solution it is Working fine, but how to implement Cascading Drop Down lists,, in my project i have to develop it for States, Districts and Mandals

    Reply
  87. StuzorJuly 23, 2013 ב 22:31

    Great Combo Box, Thanks.
    Mine throws an exception when I try to set IsEnabled = “false”

    It also doesn’t handle TabOrdering very well, for example if you add the property: KeyboardNavigation.TabIndex=”11″

    Because it doesn’t work I try to set it to be NOT a tabstop, but that doesn’t work either, as it still stops on this combo box. KeyboardNavigation.IsTabStop=”false”

    Otherwise great work, thanks

    Reply
  88. fhvskmlods@gmail.comJuly 26, 2013 ב 11:03

    My brother recommended I might like this website. He was entirely correct. This submit really produced my day. You cann’t consider merely how so much time I had spent for this information! Thank you!

    Reply
  89. GSP_TAugust 13, 2013 ב 09:43

    I’m assuming the code I’m working with came from this blog because there are just too many similarities. The control for its normal use is working fine but I’ve run into a problem that I cannot figure out. If I have a number of these checkboxes (let’s say 4 calling them A, B, C and D). If I manually set checkbox B with a selection and then checkbox C with a selection all is good. Now I have a menu item that lets me copy the settings of one checkbox to all the others. So if I select checkbox C and say “copy to all” all the settings are updated on all the checkboxes and the text is also update except for any checkbox that I set manually. So in my example above, copying C to A, B and D all the settings are updated but the text on B is not. I cannot figure out what is controlling (stopping) the update. Does anyone have any clues? I’m very new to WPF/XAML/C#.

    Reply
  90. Great control, please send me the working codeOctober 9, 2013 ב 08:14

    Great control, please send me the working code on my gmail address

    pradeepkandale@gmail.com

    Reply