IntroductionIn my article on "
Show Hide Columns In
DataGrid In WPF", we saw how to use it using CheckBoxes. In this article we will
see how we can add a ContextMenu for the Header and that will perform our
Hide/Un-Hide function.
Creating WPF Application
ProjectFire up Visual Studio 2008 and Create a WPF Application
and name the project as ContextMenuDGWPF.

First
we need to create some sample data that will be loaded into
DataGrid.
#region Employee Class
public class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailID { get; set; }
public string Contact { get; set; }
}
#endregionAbove
class is for our Employee Data to be bound to DataGrid.
Add the
following code into Constructor of the Window.
List employeeList = new List();
#region Constructor
public Window1()
{
InitializeComponent();
for (int i = 1; i <= 20; i++)
{
Employee emp = new Employee
{
ID = i,
FirstName = "FirstName" + i.ToString(),
LastName = "LastName" + i.ToString(),
EmailID = "FirstName " + i.ToString() + ".LastName" + i.ToString() + "@some.com",
Contact = "9999999" + i.ToString()
};
employeeList.Add(emp);
}
dgData.ItemsSource = employeeList;
dgData.AutoGeneratedColumns += new EventHandler(dgData_AutoGeneratedColumns);
}
#endregion
Now
run the application to see if Data is displayed!

Great!
Now
we will tweak a litle bit. We will add the event handler AutoGeneratedColumns
for DataGrid.
Add the handler in the constructor.

Code View of the above Image
#region Constructor
public Window1()
{
InitializeComponent();
for (int i = 1; i <= 20; i++)
{
Employee emp = new Employee
{
ID = i,
FirstName = "FirstName" + i.ToString(),
LastName = "LastName" + i.ToString(),
EmailID = "FirstName " + i.ToString() + ".LastName" + i.ToString() + "@some.com",
Contact = "9999999" + i.ToString()
};
employeeList.Add(emp);
}
dgData.ItemsSource = employeeList;
dgData.AutoGeneratedColumns += new EventHandler(dgData_AutoGeneratedColumns);
}
#endregionNow
in the above added event we will generate our ContextMenu.

Code view of the above Image
#region DataGrid-AutoGeneratedColumns
private void dgData_AutoGeneratedColumns(object sender, EventArgs e)
{
cxMenu = new ContextMenu();
foreach (DataGridColumn item in dgData.Columns)
{
menuItem = new MenuItem();
menuItem.Header = item.Header;
menuItem.IsChecked = true;
cxMenu.Items.Add(menuItem);
menuItem.Click += new RoutedEventHandler(menuItem_Click);
menuItem.Checked += new RoutedEventHandler(menuItem_Checked);
menuItem.Unchecked += new RoutedEventHandler(menuItem_Unchecked);
}
}
#endregionAs
you see in the above code we are looping through all the columns and adding a
MenuItem to ContextMenu each time.
We need to add the above event
handlers for MenuItem as we are going to Click/Check/Uncheck them at
runtime.
Now in the Click event we will add the following
code:
void menuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
if (item.IsChecked)
{
item.IsChecked = false;
}
else
{
item.IsChecked = true;
}
}Here
is the logic; when we click on the MenuItem only the Click event is handled, not
the Check/Uncheck event. So we have Changed the IsChecked property each time the
MenuItem is clicked. Then we can handle the Checked/Unchecked
events.
Now we will do similar thing that we did in our last
article.
Add the following code for Checked event of
MenuItem.
void menuItem_Unchecked(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
foreach (DataGridColumn column in dgData.Columns)
{
if (column.Header.ToString().Contains(item.Header.ToString()))
{
dgData.Columns.Remove(column);
break;
}
}
}Add
the following code for UnChecked event of MenuItem.
void menuItem_Checked(object sender, RoutedEventArgs e)
{
MenuItem item = sender as MenuItem;
dgData.AutoGeneratedColumns -= new EventHandler(dgData_AutoGeneratedColumns);
List menuList = new List();
menuList.Clear();
foreach (MenuItem menuItem in cxMenu.Items)
{
if (menuItem.IsChecked == false)
{
menuList.Add(menuItem.Header.ToString());
}
}
dgData.ItemsSource = null;
dgData.ItemsSource = employeeList;
foreach (string menuItem in menuList)
{
foreach (DataGridColumn column in dgData.Columns)
{
if (column.Header.ToString() == menuItem)
{
dgData.Columns.Remove(column);
break;
}
}
}
}Next
is our major part where we will handle the RightMouseButtonDown event and
identify whether we have right clicked on the Header or not.
#region DataGrid-MouseRightButtonUp
private void dgData_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
DependencyObject depObj = (DependencyObject)e.OriginalSource;
while ((depObj != null) && !(depObj is DataGridColumnHeader))
{
depObj = VisualTreeHelper.GetParent(depObj);
}
if (depObj == null)
{
return;
}
if (depObj is DataGridColumnHeader)
{
DataGridColumnHeader dgColHeader = depObj as DataGridColumnHeader;
dgColHeader.ContextMenu = cxMenu;
}
}
#endregionIt
seems we are ready. Run the application.

As
you see above we have successfully displayed the ContextMenu on Column
Header.
Now we will perform the Hide/Un-Hide
functions.

You can also download the sample project used in above example.
Hope
this article helps.