.NET Tutorials, Forums, Interview Questions And Answers
Welcome :Guest
 
Sign In
Register
 
Win Surprise Gifts!!!
Congratulations!!!


Top 5 Contributors of the Month
abhays
Clintonzz
arronlee
mattyclown
cathyhill345

Home >> Articles >> WPF >> Post New Resource Bookmark and Share   

 Subscribe to Articles

Show Hide Columns Using Context Menu In DataGrid In WPF

Posted By:Diptimaya Patra       Posted Date: April 23, 2010    Points: 25    Category: WPF    URL: http://dpatra.blogspot.com  

Show Hide Columns Using Context Menu In DataGrid In WPF. In this article we will see how we can add a ContextMenu for the Header and that will perform our Hide/Un-Hide function.
 

Introduction


In 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 Project


Fire up Visual Studio 2008 and Create a WPF Application and name the project as ContextMenuDGWPF.


1.gif

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; }
}
#endregion

Above 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!


4.gif

Great!


Now we will tweak a litle bit. We will add the event handler AutoGeneratedColumns for DataGrid.


Add the handler in the constructor.


5.gif

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);
} 
#endregion


Now in the above added event we will generate our ContextMenu.


6.gif

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);
    }
}
#endregion

As 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;
    }
}
#endregion

It seems we are ready. Run the application.


11.gif

As you see above we have successfully displayed the ContextMenu on Column Header.


Now we will perform the Hide/Un-Hide functions.


12.gif

You can also download the sample project used in above example.

Hope this article helps.


 Subscribe to Articles

     

Further Readings:

Responses

No response found. Be the first to respond this post

Post Comment

You must Sign In To post reply
Find More Articles on C#, ASP.Net, Vb.Net, SQL Server and more Here

Hall of Fame    Twitter   Terms of Service    Privacy Policy    Contact Us    Archives   Tell A Friend