It often amazes me to see how easily one can accomplish so much with WPF.
And yet, let’s admit it, its can sometimes be darned hard to achieve some fairly trivial things.
Here is a simple problem I worked quite hard on until I had a solution I was happy with. I boiled it down to a few specific techniques that can be reused, so I think they are worth sharing.
You can download the source code for this article here.
Background
Let’s say you have a business object (say Employee) with a boolean property (say IsManager). You have a collection of these objects and you want to bind them to the DataGrid of the WPFToolkit. A natural choice for representing a boolean property in the DataGrid is the DataGridCheckBoxColumn and using fairly rudimentary XAML you can two-way bind your collection to the grid.
<tk:DataGrid x:Name="gridEmployeeList"
AutoGenerateColumns="False"
>
<tk:DataGrid.Columns>
<tk:DataGridCheckBoxColumn
Header="Manager"
Binding="{Binding Path=IsManager, Mode=TwoWay}"
/>
<tk:DataGridTextColumn
Header="Name"
Width="*"
Binding="{Binding Path=Name, Mode=TwoWay}"
/>
</tk:DataGrid.Columns>
</tk:DataGrid>
</StackPanel>
(The ‘tk’ prefix is mapped to the Microsoft.Windows.Controls namespace in the WPFToolkit assembly.)
OK. You do have to write some code in order for changes to an Employee to propagate to UI. You have a choice. Either make those IsManager and Name properties Dependency Properties or implement INotifyPropertyChanged and raise the PropertyChanged event when those properties change.
As these are business objects with no dependence on UI or WPF, I prefer not to force them to inherit the DependencyObject base class so, in this article, I will be implementing the INotifyPropertyChanged interface.
The Problem
Now, here is my trivial problem.
I would like to have a CheckBox, let’s call it an aggregate CheckBox, that I can use to check and uncheck the CheckBoxes on all rows (in the DataGridCheckBoxColumn) with one click. This is quite a basic requirement for any application that will be used to present more than a few records.
A natural place to put the aggregate CheckBox would be in the Column Header above the DataGridCheckBoxColumn.
So, go on, show me how easy it is to do that with the WPF DataGrid : )
I will describe my solution in the next post…