.NET4.0 : I'm building a DataGrid in a codebehind, so I'm not using any XAML. C# only. When the user right clicks anywhere in the column header, I want to show a context menu. Here's some code to give you an idea:
public void MakeAllColumns()
{
for (int i = 0; i < AllColumnDisplayNames.Length; i++)
{
// create a new column depending on the data to be displayed
DataGridTextColumn col = new DataGridTextColumn();
col.MaxWidth = 300;
// create a new Textblock for column's header and add it to the column
TextBlock headerText = new TextBlock() { Text = AllColumnDisplayNames[i] };
col.Header = headerText;
/// create a new context menu and add it to the header
ContextMenu menu = new ContextMenu();
headerText.ContextMenu = menu;
// build the context menu depending on the property
menu.Items.Add(new Button() { Content = "FOOBAR" });
// add the bindings to the data
col.Binding = new Binding(AllColumnBindings[i]);
AllColumns.Add(AllColumnDisplayNames[i], col);
}
}
The problem with this approach is that the user needs to click on the actual TextBox in order to activate the context menu, as opposed to anywhere on the header.
As I can't think of a way to make the TextBox fill the header width, all I can think to do is change the TextBox width property to bind to the column's width. The columns stretch to fit their content, and as such they have different widths. However, when I print all the columns ActualWidth properties to console, it says that they all have width 20, which is not what my GUI looks like. How can I get the column width that corresponds to how it looks in my GUI?
To you solve your problem must exchange o your body method by this body:
This code was tested:
for (int i = 0; i < AllColumnDisplayNames.Length; i++)
{
// create a new column depending on the data to be displayed
DataGridTextColumn col = new DataGridTextColumn();
col.MaxWidth = 300;
/// create a new context menu
ContextMenu menu = new ContextMenu();
// build the context menu depending on the property
menu.Items.Add(new Button() { Content = "FOOBAR" });
// create a new column's header and add it to the column
DataGridColumnHeader head = new DataGridColumnHeader() { Content = AllColumnBindings[i] };
head.ContextMenu = menu;//add context menu to DataGridColumnHeader
col.Header = head;
// add the bindings to the data
col.Binding = new Binding(AllColumnBindings[i]);
AllColumns.Add(AllColumnDisplayNames[i], col);
}
Instead of using TextBlock
I used DataGridColumnHeader
, which has the ContextMenu
property, thus occupying all the space (height and width) of the Header
.