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:
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).
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.
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:
new DataGridViewColumnSelector(dataGridView1);
Or you can create an instance and then attach a DataGridView
using the DataGridView
property:
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