WPF Create Custom Checkbox List With ListBox Element
18-03-2015In order to use CheckBox ListBox in a WPF application, we should use custom ListBox list.
There are three steps to accomplish this:
1. Create a class which will represent items of the ListBox.
2. Create a List object consisting of the custom item class defined in step 1.
3. Add ListBox.ItemTemplate into <ListBox>
element to create CheckBox ListBox.
4. Create a custom MultiValueConverter if you want to initialize the CheckBox items to be selected or not.
Step 1: Create Country class for ListBox items
internal class Country { public string Name { get; set; } public bool Active { get; set; } }
Step 2: Initiliaze ListBox
private static void initialize() { List<Country> countryList = new List<Country>(); Country country = new Country(); countryTr.Name ="Turkey"; countryTr.Active = true; Country contryUS=new Country(); contryUS.Name = "America"; contryUS.Active = false; countryList.add(countryTr); countryList.add(countryUS); //countryTr is active, so add this object to SelectedItems collection lstCountries.SelectedItems.Add(countryTr); lstCountries.ItemsSource = countryList; }
Step 3: Custom ListBox element in XAML file
<UserControl.Resources> <converters:CollectionToBoolConverter x:Key="CollectionToBoolConverter" /> </UserControl.Resources> <ListBox Grid.Row="2" SelectionMode="Multiple" x:Name="lstCountries" Grid.Column="1" Margin="5" Width="600" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <CheckBox Content="{Binding Name}" Margin="5 5 0 0" Width="80"> <CheckBox.IsChecked> <MultiBinding Converter="{StaticResource CollectionToBoolConverter}" Mode="TwoWay"> <Binding Path="IsSelected" RelativeSource="{RelativeSource AncestorType=ListBoxItem}" /> <Binding Path="Active" /> </MultiBinding> </CheckBox.IsChecked> </CheckBox> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Line 4: We specified SelectionMode as Multiple, so we can choose multiple checkboxes.
Line 5, 6, 9: These lines are used to make ListBox style as WrapPanel.
Line 18: It is necessary to get selected checkboxes. To get SelectedItems:var selectedCheckBoxList = lstCountries.SelectedItems;
Line 19: Path="Active"
is necessary when initialize CheckBox items.
Step 4: CollectionToBoolConverter Class
public class CollectionToBoolConverter : IMultiValueConverter { /// <summary> /// Runs when initialization /// </summary> /// <param name="values">Binding values</param> /// <param name="targetType">Merged value</param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns></returns> public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { bool listBoxValue = (bool) values[0]; bool initializedValue = (bool) values[1]; return listBoxValue || initializedValue; } /// <summary> /// Runs when any ListBox element thats CheckBox element is clicked. /// This method only runs when Mode is "TwoWay" /// </summary> /// <param name="value"></param> /// <param name="targetTypes"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns></returns> public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { /*bool isChecked = (bool) value; object[] resultObjects=new object[2]; resultObjects[0] = isChecked; resultObjects[1] = isChecked; return resultObjects; */ return null; } }