WPF CheckedList Control

The latest feature added to GoalBook is filtering of data using a custom CheckedList control. WPF doesn’t provide a CheckedList control though it is possible to create a composite control using the standard ListBox and CheckBox controls. The two key challenges I found were in binding the CheckBox.IsChecked property to the ListBoxItem.IsSelected property and hiding the default blue ListBoxItem Background colour.

The appearance of the list is as expected;

CheckedList

The only code behind required is in initialising the selected items. Note the data required for populating the CheckedList is a generic Dictionary<int, string> which is set in the DataContext. A second Dictionary<int, string> allows for getting and setting the checked items.

foreach (object item in filterListBox.Items)
{
    // Get the listBoxItem belonging to the item.
    ListBoxItem listBoxItem = (ListBoxItem)this.filterListBox.ItemContainerGenerator.ContainerFromItem(item);
    KeyValuePair<int, string> content = (KeyValuePair<int, string>)listBoxItem.Content;
    
    if (this.CheckedItems.ContainsKey(content.Key))
    {
        listBoxItem.IsSelected = true;
    }
}

The XAML is as follows. The ControlTemplate is responsible for setting the background of the selected items to transparent. The ListBox’s SelectionMode is Multiple. The text displayed for each checkbox (content property) is from the bound Dictionary’s Value property. The CheckBox’s IsChecked property binds to the ListBoxItem’s IsSelected property. Note the ListBoxItem is implicitly created when the ListBox binds to its data.

<ListBox Name=”filterListBox”
    Grid.Row=”0″
    SelectionMode=”Multiple”
    BorderThickness=”0″
    Margin=”5,5,5,5″                
    ItemsSource=”{Binding Mode=OneWay}” >
    <ListBox.ItemContainerStyle>
        <Style TargetType=”ListBoxItem”>
            <Setter Property=”HorizontalContentAlignment” Value=”Stretch”/>
            <Setter Property=”HorizontalAlignment” Value=”Stretch”/>
            <Setter Property=”Template”>
                <Setter.Value>
                    <ControlTemplate TargetType=”ListBoxItem”>
                        <Border Name=”Border” Padding=”0″ SnapsToDevicePixels=”true”>
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property=”IsSelected” Value=”true”>
                                <Setter TargetName=”Border” Property=”Background” Value=”Transparent”/>
                            </Trigger>
                            <Trigger Property=”IsSelected” Value=”false”>
                                <Setter TargetName=”Border” Property=”Background” Value=”Transparent”/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin=”0,5,0,5″ Orientation=”Horizontal” >
                <CheckBox Name=”checkbox”
                    Content=”{Binding Path=Value, Mode=OneWay}”
                    VerticalContentAlignment=”Center”
                    Margin=”0,0,5,0″
                    Width=”Auto”
                    IsChecked=”{Binding RelativeSource={RelativeSource FindAncestor,
                        AncestorType={x:Type ListBoxItem}}, Path=IsSelected}”
                    IsTabStop=”False”
                    Checked=”FilterCheckbox_CheckChanged”
                    Unchecked=”FilterCheckbox_CheckChanged”/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</
ListBox>

2 Responses to WPF CheckedList Control

  1. senglory@gmail.com says:

    Don’t know why but in my case all that ListtBoxItems remain unchecked, i.e. their IsSelected remains FALSE. No matter if the proper checkbox is checked or not.

  2. office.net says:

    office.net…

    […]WPF CheckedList Control « Goal Book. Blog[…]…

Leave a comment