WPF Create Custom Checkbox List With ListBox Element

18-03-2015

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

© 2019 All rights reserved. Codesenior.COM