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