Introduction
I wanted a datagridview
where you could not only filter on the datasource
but also sort and add a theme at the same time.
Background
In some of my projects, I needed something of a filter which looks a bit like the filter options of Excel. In the next version, I also want something like grouping and freezing of columns and rows.
Using the Code
What I wanted was a small filter picture in the columnheader
of the datagridview
. If you do a horizontal scroll and the columns are visible, then the pictures must be in the correct position. In the call of the paint
event, there is the method I used for that purpose. If the column is of the type DataGridViewImageColumn
, then there is no display a filter picture.
private void Grid_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
PaintFiltersOnColumnsHeaders(e);
}
private void PaintFiltersOnColumnsHeaders(PaintEventArgs e)
{
Graphics gr = e.Graphics;
for (int colIdx = 0; colIdx < _grid.Columns.Count; colIdx++)
{
if (IsColumnDisplayed(colIdx))
{
Type colType = _grid.Columns[colIdx].GetType();
if (colType != typeof(DataGridViewImageColumn))
{
if (_filters[colIdx] != null)
{
if (_filters[colIdx].IsFilter)
{
DrawFilter(colIdx, icoIsFilter, gr);
}
else
{
DrawFilter(colIdx, icoNoFilter, gr);
}
}
else
{
DrawFilter(colIdx, icoNoFilter, gr);
}
}
}
}
}
Here the code to draw the filter picture on the columnheader
:
private void DrawFilter(int colIdx, Image ico, Graphics gr)
{
Rectangle rect = _grid.GetCellDisplayRectangle(colIdx, -1, true);
if (rect.Width > 20)
{
Rectangle rectPicture = new Rectangle
{
Width = 18,
Height = rect.Height - 12,
Location = new Point(rect.Left + (rect.Width - 20), rect.Top + 6)
};
gr.DrawImage(ico, rectPicture);
}
}
If you click on the filter picture in the column header, then a form will be shown. With that form, you can select some filter options. You can also deselect a filter on a column. To deselect all the filters, right click in the grid and reset all filters.
If you right click on the grid, then you have several options. You can sort and you can reset all the filters. For the sorting, you have to set the sortmode
for all the columns. With the change of the datasource
, you can set the correct sort mode. With the last method, you can set the sort direction.
private void BaseDataGrid_DataSourceChanged(object sender, EventArgs e)
{
ColumnFilter.ResetFilters();
ColumnSorter.SetSortMode();
}
public void SetSortMode()
{
for (int colTeller = 0; colTeller < _grid.Columns.Count; colTeller++)
{
_grid.Columns[colTeller].SortMode = DataGridViewColumnSortMode.Programmatic;
}
}
public void SortZA(int colIdx)
{
_sortDirection = 1;
SetSorted(colIdx);
}
For setting the theme, there is an interface for making your one. In this example, there is a theme include. I hope that the example will lead to new themes.
History
- Version 19 December 2018 is the first.