#981 – Including a CheckBox with Each Item in a ListBox

By default, a ListBox shows the selection state of each item in the list using a different brush.  If you want to make the selection of each item more obvious and not force the user to use Ctrl or Shift keys to multi-select items, you can render each item as a CheckBox.

Assume that we bind to a a list of Actor objects, where Actor has IsFav (boolean) and NameAndDates (string) properties, you can do the following:

        <ListBox Name="lbActors" Margin="15" Width="200" Height="190"
                 ItemsSource="{Binding ActorList}">
            <!-- Because CheckBox indicates selection, hide standard ListBox -->
            <!-- selection behavior -->
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Focusable" Value="False"/>
                </Style>
            </ListBox.ItemContainerStyle>
            <!-- Each item in list is a CheckBox -->
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox Content="{Binding NameAndDates}" IsChecked="{Binding IsFav}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

As you check each item, the IsFav property in the corresponding Actor object is set/cleared.

981-001

#854 – Clicked vs. Checked/Unchecked Events for CheckBox

If you want to add an event handler for a CheckBox that gets executed whenever a user clicks on the CheckBox, you can take one of two different approaches:

  • Add a handler for the Click event and then check the IsChecked property to discover the new state (checked / unchecked / indeterminate)
  • Handle one or more of the specific events for the individual states–Checked, Unchecked or Indeterminate

When a user clicks on the CheckBox, the specific event (e.g. Checked) is fired, followed by the Click event.

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            CheckBox cb = sender as CheckBox;
            string checkState;

            if (!cb.IsChecked.HasValue)
                checkState = "Indeterminate";
            else
            {
                if (cb.IsChecked == true)
                    checkState = "Checked";
                else
                    checkState = "Unchecked";
            }

            Trace.WriteLine(string.Format("Click event: {0}", checkState));
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("Checked event");
        }

        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("Unchecked event");
        }

        private void CheckBox_Indeterminate(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("Indeterminate event");
        }

854-001

#853 – A CheckBox Can Always Be in an Indeterminate State

If you set the IsThreeState property of a CheckBox to true, the user can cycle the CheckBox through three states, rather than true–checked, not checked and indeterminate.

<CheckBox Content="I cycle through 3 states" IsThreeState="True"/>

853-001
853-002
853-003
If the IsThreeState property is set to false, the user can only cycle the CheckBox through the checked and unchecked states.  You can, however, still set the CheckBox to an indeterminate state using data binding or from code.

        <CheckBox Name="chkTest" Content="I cycle through 2 states" IsThreeState="False"/>
        <Button Content="Set Indeterminate" Click="Button_Click" Margin="15"/>

</span>
<pre>        private void Button_Click(object sender, RoutedEventArgs e)
        {
            chkTest.IsChecked = null;
        }

853-004

#852 – Setting a Three-State CheckBox to an Indeterminate Value

A three-state CheckBox can take on one of three values: true, false, or indeterminate.  You can use data binding to get/set the value of a three-state CheckBox, binding the control to a nullable bool.

You can also explicitly set the value of a CheckBox, in either XAML or code.

To set a CheckBox to an indeterminate value in code, just set its IsChecked property to null.

            chkPie.IsChecked = null;

852-001
To set a CheckBox to an indeterminate value in XAML, set its IsChecked property to {x:Null}.

        <CheckBox Name="chkPie" Content="I Like Pie" IsThreeState="True"
                  IsChecked="{x:Null}"/>

#833 – CheckBox is a ContentControl

CheckBox control derives from ContentControl, which means that it can contain a single piece of content.  In the case of a CheckBox, this content is rendered next to the actual check box that a user can check on or off.

You typically set the content of a CheckBox to a string, which gets rendered next to the check box.

        <CheckBox Content="Learn to juggle"/>
        <CheckBox Content="Read War and Peace"/>
        <CheckBox Content="Visit Japan"/>

833-001
You can, however, set the Content property to anything that you like, including a panel that contains other controls.

        <CheckBox VerticalContentAlignment="Center">
            <CheckBox.Content>
                <StackPanel>
                    <Image Source="Juggler.png" Height="85"/>
                    <Label Content="Learn to juggle"/>
                </StackPanel>
            </CheckBox.Content>
        </CheckBox>
        <CheckBox VerticalContentAlignment="Center">
            <CheckBox.Content>
                <StackPanel>
                    <Image Source="leo.jpg" Height="85"/>
                    <Label Content="Read War and Peace"/>
                </StackPanel>
            </CheckBox.Content>
        </CheckBox>
        <CheckBox VerticalContentAlignment="Center">
            <CheckBox.Content>
                <StackPanel>
                    <Image Source="kinkakuji.jpg" Height="85"/>
                    <Label Content="Visit Japan"/>
                </StackPanel>
            </CheckBox.Content>
        </CheckBox>

833-002

#825 – Two Way Binding for a CheckBox

You can bind the IsChecked property of a CheckBox to a boolean variable, so that the variable will always reflect the current value of the CheckBox in the user interface.

You can also do two-way binding, where the boolean variable changes when the user toggles the CheckBox, but the CheckBox also toggles when the value of the variable changes.

        <Label Content="Things my dog can do:"/>
        <CheckBox Content="Sit" IsChecked="{Binding CanSit, Mode=TwoWay}"/>
        <CheckBox Content="Stay" IsChecked="{Binding CanStay, Mode=TwoWay}"/>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="Report State" Click="btnReportState_Click"
                    Margin="5"/>
            <Button Content="Change State" Click="btnChangeState_Click"
                    Margin="5"/>
        </StackPanel>

Code-behind:

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private bool canSit;
        public bool CanSit
        {
            get { return canSit; }
            set
            {
                canSit = value;
                RaisePropertyChanged("CanSit");
            }
        }

        private bool canStay;
        public bool CanStay
        {
            get { return canStay; }
            set
            {
                canStay = value;
                RaisePropertyChanged("CanStay");
            }
        }

        public MainWindow()
        {
            this.InitializeComponent();
            this.DataContext = this;
        }

        private void btnReportState_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(string.Format("Sit: {0}, Stay: {1}", CanSit, CanStay));
        }

        private void btnChangeState_Click(object sender, RoutedEventArgs e)
        {
            CanSit = CanSit ? false : true;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

#540 – Adding Common Controls in Blend

You can add various common controls to your application in Blend using buttons on the tools panel.  You select the icon for the control that you want to add and then double-click the icon to add it.

If you left-click and hold on the Button icon on the tools panel, or right-click, you’ll see a series of controls that you can insert by clicking on the icon at this location in the tools panel.

  • Button – Click on a button to perform some action
  • CheckBox – Check an item in a list
  • ComboBox – Select an item from a dropdown list
  • ListBox – Select an item from a list
  • RadioButton – Select one item from a group
  • ScrollBar – Scroll stuff
  • Slider – Pick a value from a range
  • TabControl – Switch between separate tabbed parts of app
  • GridSplitter – Make section of app bigger/smaller

Select the control that you want and then double-click to add to your GUI.