Introduction

This little sample shows how to add a "select all" checkbox to the column header of a datagrid.
 

Building the Sample

Just download, unblock, unzip, load and run!
 
 
Description
The problem with binding to elements in a DataGrid ColumnHeader is that the column header is a generated part of the control that does not have access to the DataGri'd DataContext.
The trick is there to use "RelativeSource AncestorType=" to find a source for binding. This will traverse back down the generated VisualTree, looking for a control of the defined AnsestorType. Once it finds the targetted control type, it uses that parent object's DataContext in the Path declaration, as it is the property of the object we want to use, then we refer to the AllSelected property of the DataContext.
 
XAML
Edit|Remove
<DataGridTemplateColumn.HeaderTemplate> 
    <DataTemplate> 
        <CheckBox Margin="6,0" IsChecked="{Binding DataContext.AllSelected, RelativeSource={RelativeSource AncestorType=Window}}" /> 
    </DataTemplate> 
</DataGridTemplateColumn.HeaderTemplate>
 
The "select all" checkbox IsChecked has a binding to a property back in the code-behind (or ViewModel) where we use the setter to select all the items:
 
C#
Edit|Remove
bool _AllSelected; 
public bool AllSelected 
{ 
    get 
    { 
        return _AllSelected; 
    } 
    set 
    { 
        if (_AllSelected != value) 
            _AllSelected = value; 
 
        foreach (var user in Users) 
            user.Selected = value; 
    } 
}
A final point worth highlighting is INotifyPropertyChanged must be implemented on the item class, so that changing it's Selected property is reflected in the UI, showing all the checkboxes as checked. if you removed the following line:
C#
Edit|Remove
RaisePropertyChanged("Selected");
 ..you would find that the checkboxes do not show as selected.
 
 
 

Source Code Files