WPF DataGrid CheckBox Single Click Checking/Unchecking

WPF DataGrid has a very annoying behaviour of forcing users to click twice on a checkbox in order to check or uncheck it. There are a number of solutions proposing handling mouse preview events and switching a DataGrid into the edit mode manually. The problem with such solutions is that the require writing quite a lot of extra code that seems to be an overkill for such a minor, yet irritating problem. I propose a better option, to use a DataGridTemplateColumn instead of DataGridCheckBoxColumn.

Indeed, you can easily place a CheckBox inside a DataGridTemplateColumn, bind it to a corresponding property and it will be checkable/uncheckable with a single click.

XAML:

<DataGrid Name="dgProducts" AutoGenerateColumns="False" CurrentCellChanged="dgProducts_CurrentCellChanged">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
        <DataGridTextColumn Header="Price" Binding="{Binding Path=Price}"/>
        <DataGridTemplateColumn Header="In Stock">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding Path=IsInStock}">
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Code-behind:

   1:  public partial class MainWindow : Window
   2:      {
   3:          ProductsEntities db = new ProductsEntities();
   4:   
   5:          public MainWindow()
   6:          {
   7:              InitializeComponent();
   8:   
   9:              var products = from p in this.db.Products
  10:                             select p;
  11:   
  12:              dgProducts.ItemsSource = products;
  13:          }
  14:   
  15:          private void dgProducts_CurrentCellChanged(object sender, EventArgs e)
  16:          {
  17:              this.db.SaveChanges();
  18:          }
  19:  }

However, this piece of code still has a problem, in order to send update to a database user must edit any other column after modifying a checkbox. But it’s pretty easy to overcome this issue, first of all, we have to put UpdateSourceTrigger=”PropertyChanged” to the binding section of a checkbox and then handle its Click event.

XAML:

<CheckBox IsChecked="{Binding Path=IsInStock, UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_Click"/>

Code-Behind:

   1:  private void CheckBox_Click(object sender, RoutedEventArgs e)
   2:  {
   3:      MessageBox.Show("click");
   4:      this.db.SaveChanges();
   5:  }

Mike Borozdin

Monday, June 13, 2011

blog comments powered by Disqus