0

I am looking for a WPF combo box with checkboxes. I reffered to the below link and used the solution given by Sergey. Looking for a WPF ComboBox with checkboxes

The solution provided works fine but I am not sure how the binding to the combo box is done. I am new to WPF so it would be great if I could get any help on this. XAML code:

<Window x:Class="WpfApplication1.StackCombo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="StackCombo" Height="338" Width="533">
<Grid>
    <ComboBox Name="cbObjects" VerticalAlignment="Center" Margin="103,140,280,138" SelectionChanged="OnCbObjectsSelectionChanged" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding IsSelected}" Width="20" VerticalAlignment="Center" Checked="OnCbObjectCheckBoxChecked" Unchecked="OnCbObjectCheckBoxChecked" />
                    <TextBlock Text="{Binding}" VerticalAlignment="Center" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    <TextBlock IsHitTestVisible="False" Name="tbObjects" Text="None" VerticalAlignment="Center" Margin="113,100,268,184" />
</Grid>

This is the code Behind:

public partial class StackCombo : Window
    {
    public StackCombo()
    {
        ObservableCollection<SelectableObject<Person>> _list;
        InitializeComponent();
        _list = new ObservableCollection<SelectableObject<Person>>();            
        _list.Add(new SelectableObject<Person>(new Person("DEF")));            
        cbObjects.ItemsSource = _list;                                   
    }

    private class Person
       {
            public Person(String firstName)
            {
                this.firstName=firstName;                    
            }
            private String firstName;          
            public String FirstName
            {
                get { return firstName; }
                set { firstName = value; }
            }               
        }

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

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

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

Thanks, Ramkumar

mabu
  • 45
  • 3
  • 9
Ram_3339983
  • 1
  • 1
  • 3
  • for binding you need to use ItemSource, are you using MVVM pattern? – Arijit Mukherjee Jul 15 '14 at 09:41
  • 1
    If you want to use WPF, it is essential to understand how data binding works. You should perhaps first read a WPF book to understand all the basics before starting to write WPF programs. At least you should read the [Data Binding Overview](http://msdn.microsoft.com/en-us/library/ms752347.aspx) article on MSDN. – Clemens Jul 15 '14 at 09:45
  • @ArijitMukherjee Yes I use the ItemSource but I am getting the object bound to the combo box instead of the value. Yes I use the MVVM pattern. – Ram_3339983 Jul 15 '14 at 09:47

1 Answers1

0

Change your code :

<ComboBox Name="cbObjects" VerticalAlignment="Center" Margin="103,140,280,138" SelectionChanged="OnCbObjectsSelectionChanged" >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsSelected}" Width="20" VerticalAlignment="Center" Checked="OnCbObjectCheckBoxChecked" Unchecked="OnCbObjectCheckBoxChecked" />
                <TextBlock Text="{Binding}" VerticalAlignment="Center" />
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

to

<ComboBox Name="cbObjects" VerticalAlignment="Center" Margin="103,140,280,138" SelectionChanged="OnCbObjectsSelectionChanged" >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox Content="{Binding FirstName}" IsChecked="{Binding IsSelected}" Width="20" VerticalAlignment="Center" Checked="OnCbObjectCheckBoxChecked" Unchecked="OnCbObjectCheckBoxChecked" />
                <TextBlock Text="{Binding}" VerticalAlignment="Center" />
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

For Reference Follow :

Code Project Article

Arijit Mukherjee
  • 3,817
  • 2
  • 31
  • 51
  • I get the "binding constraints" exception on changing the code as mentioned. From the code you can see that FirstName is present under ObjectData of SelectableObject class. – Ram_3339983 Jul 15 '14 at 11:15
  • I used the solution suggested by Sergey in below link. http://stackoverflow.com/questions/859227/looking-for-a-wpf-combobox-with-checkboxes – Ram_3339983 Jul 15 '14 at 11:17
  • did u tried changing FirstName to ObjectData.FirstName? – Arijit Mukherjee Jul 15 '14 at 11:26
  • Works for me, but is there a way to display in the selected item the number of selected elements ? – Florence Feb 07 '23 at 13:09