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