Reputation: 651
I want the context menu for a DataGrid's column headers to be different than the rest of the cells. So using the regular ContextMenu property is not going to work. There is DataGrid.RowHeaderTemplate, but I can't find DataGrid.ColumnHeaderTemplate.
Edit/Note: Columns are generated dynamically.
Upvotes: 17
Views: 19085
Reputation: 978
If you want this to be done fully on code behind below is the approach.
using System.Windows.Controls.Primitives;
private void dgFormat_PreviewMouseRightButtonDown(object sender,
MouseButtonEventArgs e)
{
ContextMenu cm = new ContextMenu();
MenuItem miOne = new MenuItem();
miOne.Header = "One";
miOne.Click += MiOne_Click;
MenuItem miTwo = new MenuItem();
miTwo.Header = "Two";
miTwo.Click += MiTwo_Click;
cm.Items.Add(miOne);
cm.Items.Add(miTwo);
dgFormat.ContextMenu = cm;
dgFormat.ContextMenu.Visibility = Visibility.Collapsed;
DependencyObject depObj = (DependencyObject)e.OriginalSource;
while (depObj != null &&
!(depObj is DataGridColumnHeader))
{
depObj = VisualTreeHelper.GetParent(depObj);
}
if (depObj == null)
{
return;
}
if (depObj is DataGridColumnHeader)
{
DataGridColumnHeader colHeader = depObj as DataGridColumnHeader;
if (colHeader.Content.ToString() == "First Name")
{
dgFormat.ContextMenu.Visibility = Visibility.Visible;
}
}
}
private void MiOne_Click(object sender,
RoutedEventArgs e)
{
MessageBox.Show("One");
}
private void MiTwo_Click(object sender,
RoutedEventArgs e)
{
MessageBox.Show("Two");
}
Upvotes: 1
Reputation: 3933
It depends on how you are generating your columns, if you are defining them in XAML then you could do this:
<DataGrid DataContext="{Binding MyDataContext}" ItemsSource="{Binding MyItems}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Age}" Header="Age" >
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{TemplateBinding Content}" >
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Task _1" />
<MenuItem Header="Task _2" />
<MenuItem Header="Task _3" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
Upvotes: 1
Reputation: 19885
Target a common Style to all DataGridColumnHeaders:
<DataGrid.Resources>
<ContextMenu x:Key="DataGridColumnHeaderContextMenu" ...>
</ContextMenu>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContextMenu"
Value="{StaticResource DataGridColumnHeaderContextMenu}" />
</Style>
</DataGrid.Resources>
If you want different context menus for different column headers then use triggers:
<DataGrid.Resources>
<ContextMenu x:Key="ColumnHeaderContextMenu1" ...>
</ContextMenu>
<ContextMenu x:Key="ColumnHeaderContextMenu2" ...>
</ContextMenu>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Triggers>
<Trigger Property="Content" Value="Column1">
<Setter Property="ContextMenu"
Value="{StaticResource ColumnHeaderContextMenu1}" />
</Trigger>
<Trigger Property="Content" Value="Column2">
<Setter Property="ContextMenu"
Value="{StaticResource ColumnHeaderContextMenu2}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
Hope that helps.
Upvotes: 31