Click here to Skip to main content
15,888,579 members
Articles / Desktop Programming / Windows Forms
Article

A DataGridView Column Show/Hide Popup

Rate me:
Please Sign up or sign in to vote.
4.80/5 (56 votes)
23 Dec 2008CPOL1 min read 198.5K   9K   152   50
A class adding column show/hide capability to a DataGridView

Introduction

Many applications offer users a useful feature to show/hide columns of data. In Windows Forms, the control dedicated to show tabular data is DataGridView but there isn't a built-in column selection mechanism. I wrote the small class DataGridViewColumnSelector to fill this void.

Background

The <code>DataGridViewColumnSelector class is a new class and not a derivation of the DataGridView class. You don't need to change your DataGridView instances declarations. Simply create an instance of DataGridViewColumnSelector and attach a DataGridView instance to it. When the user right-clicks the cell origin, a pupup is shown, allowing to check/uncheck the columns to show.

The column list is implemented through a CheckedListBox and the popup effect is achieved by means of a ToolStripDropDown object to which a ToolStripControlHost object is added. The latter contains the CheckedListBox. Read the article, "How to: Wrap a Windows Forms Control with ToolStripControlHost", to get some background.

Here is the constructor code:

C#
// The constructor creates an instance of CheckedListBox and ToolStripDropDown.
// the CheckedListBox is hosted by ToolStripControlHost, which in turn is
// added to ToolStripDropDown.
public DataGridViewColumnSelector() {
	mCheckedListBox = new CheckedListBox();
	mCheckedListBox.CheckOnClick = true;
	mCheckedListBox.ItemCheck += 
		new ItemCheckEventHandler(mCheckedListBox_ItemCheck);

	ToolStripControlHost mControlHost = new ToolStripControlHost(mCheckedListBox);
	mControlHost.Padding = Padding.Empty;
	mControlHost.Margin = Padding.Empty;
	mControlHost.AutoSize = false;

	mPopup = new ToolStripDropDown();
	mPopup.Padding = Padding.Empty;
	mPopup.Items.Add(mControlHost);
}

When user right-clicks the cell origin, the mDataGridView_CellMouseClick is called. It clears and fills the CheckedListBox with columns header text. Then it shows the popup. In this way, the CheckedListBox items are always refreshed to reflect changes that occurred in DataGridView columns (column additions or name changes and so on).

C#
void mDataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
	if (e.Button == MouseButtons.Right && e.RowIndex==-1 && e.ColumnIndex==-1) {
		mCheckedListBox.Items.Clear();
		foreach (DataGridViewColumn c in mDataGridView.Columns){
			mCheckedListBox.Items.Add(c.HeaderText, c.Visible);
		}
		int PreferredHeight = (mCheckedListBox.Items.Count * 16) + 7;
		mCheckedListBox.Height = (PreferredHeight < MaxHeight) ? 
					PreferredHeight : MaxHeight;
		mCheckedListBox.Width = this.Width;
		mPopup.Show(mDataGridView.PointToScreen(new Point (e.X,e.Y)));
	}
}

Finally, when user checks/unchecks a checkbox, the related column visibility is switched by mCheckedListBox_ItemCheck event handler.

C#
void mCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e){
	mDataGridView.Columns[e.Index].Visible = (e.NewValue == CheckState.Checked);
}

Using the Code

Copy the DataGridViewColumnSelector.cs file to your project. Change the namespace if you need.

You can pass the DataGridView instance directly as constructor parameter:

C#
new DataGridViewColumnSelector(dataGridView1);

Or you can create an instance and then attach a DataGridView using the DataGridView property:

C#
DataGridViewColumnSelector cs = new DataGridViewColumnSelector();
cs.DataGridView = dataGridView1;
cs.MaxHeight = 200;
cs.Width = 110;

Optionally use MaxHeight and Width properties to adjust the size of the popup.

History

  • 23rd December, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
Italy Italy
I'm a graduate in Computer Science.
I work with Metatrader MQL4,MQL5 / C# / Asp.Net / Windows Forms / SQL Server / Access / VBA / HTML / CSS / Javascript / classic C/C++.


I also like writing songs and playing around with my band Diversamente Rossi.
This is the video of the song Un'altra estate from the album L'immobile disegno.



"Short code, good code"

Comments and Discussions

 
GeneralMy vote of 5 Pin
Jeremy Hodge 20225-Oct-22 3:18
Jeremy Hodge 20225-Oct-22 3:18 
QuestionMy Vote is Five Pin
Member 1497935425-Apr-21 4:27
Member 1497935425-Apr-21 4:27 
QuestionGreat Job! Still relevant 10 years on! Pin
Chris J-1378676018-Apr-18 12:02
professionalChris J-1378676018-Apr-18 12:02 
QuestionVB.net version Pin
SumitSaha25-Apr-15 23:19
SumitSaha25-Apr-15 23:19 
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Windows.Forms
Imports System.Drawing

Public Class DataGridViewColumnSelector
' the DataGridView to which the DataGridViewColumnSelector is attached
Private WithEvents mDataGridView As DataGridView = Nothing
' a CheckedListBox containing the column header text and checkboxes
Public WithEvents mCheckedListBox As New CheckedListBox
'Private mCheckedListBox As CheckedListBox 'original code
' a ToolStripDropDown object used to show the popup
Private mPopup As ToolStripDropDown

''' <summary>
''' The max height of the popup
''' </summary>
Public MaxHeight As Integer = 300
''' <summary>
''' The width of the popup
''' </summary>
Public Width As Integer = 200
'Public Event mDataGridView_CellMouseClick()
''' <summary>
''' Gets or sets the DataGridView to which the DataGridViewColumnSelector is attached
''' </summary>
Public Property DataGridView() As DataGridView
Get
Return mDataGridView
End Get

Set(ByVal value As DataGridView)
' If any, remove handler from current DataGridView
If Not (mDataGridView Is Nothing) Then
'mDataGridView.CellMouseClick -= New DataGridViewCellMouseEventHandler(AddressOf mDataGridView_CellMouseClick)
RemoveHandler mDataGridView.CellMouseClick, New DataGridViewCellMouseEventHandler(AddressOf mDataGridView_CellMouseClick)
End If
' Set the new DataGridView
mDataGridView = value
' Attach CellMouseClick handler to DataGridView
If Not (mDataGridView Is Nothing) Then
'mDataGridView.CellMouseClick += New DataGridViewCellMouseEventHandler(AddressOf mDataGridView_CellMouseClick)
AddHandler mDataGridView.CellMouseClick, New DataGridViewCellMouseEventHandler(AddressOf mDataGridView_CellMouseClick)
End If
End Set
End Property

' When user right-clicks the cell origin, it clears and fill the CheckedListBox with
' columns header text. Then it shows the popup.
' In this way the CheckedListBox items are always refreshed to reflect changes occurred in
' DataGridView columns (column additions or name changes and so on).
'Public Event mDataGridView_CellMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs)

Private Sub mDataGridView_CellMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles mDataGridView.CellMouseClick 'original code
If e.Button = MouseButtons.Right AndAlso e.RowIndex = -1 AndAlso e.ColumnIndex = -1 Then
mCheckedListBox.Items.Clear()
For Each c As DataGridViewColumn In mDataGridView.Columns
mCheckedListBox.Items.Add(c.HeaderText, c.Visible)
Next
Dim PreferredHeight As Integer = (mCheckedListBox.Items.Count * 16) + 7
mCheckedListBox.Height = If((PreferredHeight < MaxHeight), PreferredHeight, MaxHeight)
mCheckedListBox.Width = Me.Width
mPopup.Show(mDataGridView.PointToScreen(New Point(e.X, e.Y)))
End If
End Sub
'end event

' The constructor creates an instance of CheckedListBox and ToolStripDropDown.
' the CheckedListBox is hosted by ToolStripControlHost, which in turn is
' added to ToolStripDropDown.
Public Sub New()
mCheckedListBox = New CheckedListBox()
mCheckedListBox.CheckOnClick = True
'mCheckedListBox.ItemCheck += New ItemCheckEventHandler(AddressOf mCheckedListBox_ItemCheck)
AddHandler mCheckedListBox.ItemCheck, New ItemCheckEventHandler(AddressOf mCheckedListBox_ItemCheck)

Dim mControlHost As New ToolStripControlHost(mCheckedListBox)
mControlHost.Padding = Padding.Empty
mControlHost.Margin = Padding.Empty
mControlHost.AutoSize = False

mPopup = New ToolStripDropDown()
mPopup.Padding = Padding.Empty
mPopup.Items.Add(mControlHost)
End Sub

Public Sub New(ByVal dgv As DataGridView)
Me.New()
Me.DataGridView = dgv
End Sub

' When user checks / unchecks a checkbox, the related column visibility is
' switched.
Private Sub mCheckedListBox_ItemCheck(ByVal sender As Object, ByVal e As ItemCheckEventArgs) Handles mCheckedListBox.ItemCheck
mDataGridView.Columns(e.Index).Visible = (e.NewValue = CheckState.Checked)
End Sub
End Class
AnswerRe: VB.net version Pin
Member 1177279214-May-20 0:55
Member 1177279214-May-20 0:55 
QuestionDoing in VB.Net Pin
Member 1135699225-Apr-15 11:40
Member 1135699225-Apr-15 11:40 
GeneralGood Job. Many Thanks Pin
Nilkanth Naik19-Mar-15 21:22
Nilkanth Naik19-Mar-15 21:22 
QuestionVertical scrollbar? Pin
Member 110697335-Dec-14 2:08
Member 110697335-Dec-14 2:08 
QuestionmCheckedListBox_ItemCheck not everywhere firing Pin
Member 1014656710-Feb-14 21:23
Member 1014656710-Feb-14 21:23 
QuestionSaving the settings Pin
Member 1020482612-Aug-13 7:18
Member 1020482612-Aug-13 7:18 
GeneralMy vote of 5 Pin
Ali_IND7-Jun-13 21:43
Ali_IND7-Jun-13 21:43 
QuestionThank you very much! Pin
miteleda9-Nov-12 15:23
miteleda9-Nov-12 15:23 
QuestionSave column selection Pin
MJhaa5-Nov-12 8:57
MJhaa5-Nov-12 8:57 
GeneralMy vote of 5 Pin
MJhaa31-Oct-12 7:38
MJhaa31-Oct-12 7:38 
GeneralMy vote of 5 Pin
Vincent Paukgyi24-Sep-12 22:22
Vincent Paukgyi24-Sep-12 22:22 
QuestionGood Job Pin
Aliasgar M, Maimoon6-Sep-12 23:54
Aliasgar M, Maimoon6-Sep-12 23:54 
GeneralMy vote of 5 Pin
ProEnggSoft29-Feb-12 19:21
ProEnggSoft29-Feb-12 19:21 
Questionthanks your code! Pin
caohit18-Feb-12 3:15
caohit18-Feb-12 3:15 
QuestionWhat If I have Columns That Must Stay Hidden? Pin
pointeman130-Dec-11 3:01
pointeman130-Dec-11 3:01 
QuestionIt does not work when the datagridview has a contextmenu object Pin
wuhuacong20-Aug-11 17:14
wuhuacong20-Aug-11 17:14 
GeneralMy vote of 5 Pin
Member 79087416-Jul-11 9:14
Member 79087416-Jul-11 9:14 
GeneralThanks for your info.. Pin
YZK29-Mar-11 22:32
YZK29-Mar-11 22:32 
GeneralThanks Pin
YZK29-Mar-11 22:30
YZK29-Mar-11 22:30 
GeneralMy vote of 5 Pin
snake2k3y@rambler.ru18-Mar-11 20:57
snake2k3y@rambler.ru18-Mar-11 20:57 
GeneralMy vote of 5 Pin
btaz12523-Feb-11 1:18
btaz12523-Feb-11 1:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.