I do this as follows.
I derive from the grid an add an ICommand called HideShowColumnCommand that takes as its parameter a DataGridColumn (the one i want to hide or show) and hides the column if it is visible, and shows it if it is not.
then i use a tricky context menu that i attach to the column header that has a tick that shows the column visible/hidden state..
The context menu looks like so
<ContextMenu
ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Column.DataGridOwner.Columns}">
<ContextMenu.Resources>
<local:DataGridHeaderVisibilityToBooleanConverter
x:Key="visibilityConverter" />
<BooleanToVisibilityConverter
x:Key="VisibilityOfBool" />
<DataTemplate
DataType="{x:Type DataGridColumn}">
<ContentPresenter
Content="{Binding Path=Header}"
RecognizesAccessKey="True" />
</DataTemplate>
</ContextMenu.Resources>
<ContextMenu.ItemContainerStyle>
<Style
TargetType="MenuItem">
<!--Warning dont change the order of the following two setters
otherwise the command parameter gets set after the command fires,
not much use eh?-->
<Setter
Property="CommandParameter"
Value="{Binding Path=.}" />
<Setter
Property="Command"
Value="{Binding Path=DataGridOwner.HideShowColumnCommand}" />
<Setter
Property="IsChecked"
Value="{Binding Path=Visibility, Converter={StaticResource visibilityConverter}}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
the converter like this
public class DataGridHeaderVisibilityToBooleanConverter :IValueConverter{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
try {
Visibility visibility = (Visibility)value;
if (visibility == Visibility.Visible) {
return true;
}
else {
return false;
}
}
catch { }
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
#endregion
}