Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

上一篇 Winform系列——好看的DataGridView折叠控件 中主要介绍了DataGridview的表格多级折叠功能。这章主要介绍下最近封装的另一个DataGridview表格高级过滤的功能。此功能也是参照codeproject上面的源码改写的,代码可能有源码的内容,也有本人改写过的,所以看上去可能有点乱。废话不多说,上图:

1、一般的DataGridview效果:

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

2、增加了列上面右键效果:

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

3、升序和降序就没什么说的了,看看点击过滤的效果吧:

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

4、取消某一个字段过滤的方式有两种:

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

5、取消所有字段的过滤:

Winform系列——好用的DataGridview过滤控件(表格的高级搜索功能)

大致效果就如上了。代码有点乱,如果有时间我会整理下,有兴趣的可以看看。

1、向外暴露的使用类:这个类主要功能是通过构造函数 public DgvFilterManager(DataGridView dataGridView, bool autoCreateFilters){}将DataGridview对象传进来,然后再给DataGridview增加事件和方法实现的。代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
using System.ComponentModel;
using Ewin.Client.Frame;
using Ewin.Client.Frame.Controls;
using System.Collections;
using System.Reflection; namespace Ewin.Client.Frame.UcGrid
{
public class DgvFilterManager
{ #region PRIVATE FIELDS private DgvBaseFilterHost mFilterHost; // The host UserControl to popup
private DataGridView mDataGridView; // The DataGridView to which apply filtering
private DataView mBoundDataView; // The DataView to which the DataGridView is bound
BindingSource mBindingSource; // The BindingSource, if any, to which the DataGridView is bound private string mBaseFilter = ""; // Developer provided filter expression
private int mCurrentColumnIndex = -; // Column Index of currently visibile filter private List<DgvBaseColumnFilter> mColumnFilterList; // List of ColumnFilter objects
private bool mAutoCreateFilters = true;
private bool mFilterIsActive = false; ContextMenuStrip oMenuStrip;
#endregion #region EVENTS /// <summary>
/// Occurs when a <i>column filter</i> instance for a column is about to be automatically created.
/// </summary>
/// <remarks>
/// Using this event you can set the <see cref="ColumnFilterEventArgs.ColumnFilter"/>
/// property to force the <see cref="DgvBaseColumnFilter"/> specialization to use for the
/// column.
/// This event is raised only if <see cref="DgvFilterManager.AutoCreateFilters"/> is true.
/// </remarks>
public event ColumnFilterEventHandler ColumnFilterAdding; /// <summary>
/// Occurs when a <i>column filter</i> instance is created.
/// This event is raised only if <see cref="DgvFilterManager.AutoCreateFilters"/> is true.
/// </summary>
public event ColumnFilterEventHandler ColumnFilterAdded; /// <summary>
/// Occurs when the popup is about to be shown
/// </summary>
/// <remarks>
/// Use this event to customize the popup position. Set the Handled property of the event argument to <c>true</c>.
/// </remarks>
public event ColumnFilterEventHandler PopupShowing; #endregion #region CONSTRUCTORS /// <summary>
/// Initializes a new instance of the <see cref="DgvFilterManager"/> class.
/// </summary>
public DgvFilterManager() { } /// <summary>
/// Initializes a new instance of the <see cref="DgvFilterManager"/> class.
/// </summary>
/// <param name="dataGridView">The <b>DataGridView</b> to which attach filtering capabilities</param>
/// <param name="autoCreateFilters">if set to <c>true</c> automatically creates a <i>column filter</i> for each column</param>
public DgvFilterManager(DataGridView dataGridView, bool autoCreateFilters)
{
this.mAutoCreateFilters = autoCreateFilters;
this.DataGridView = dataGridView;
} /// <summary>
/// Initializes a new instance of the <see cref="DgvFilterManager"/> class.
/// </summary>
/// <param name="dataGridView">The <b>DataGridView</b> to which attach filtering capabilities.</param>
public DgvFilterManager(DataGridView dataGridView) : this(dataGridView, true) { } #endregion #region PROPERTIES /// <summary>
/// Gets or sets a value indicating whether the manager must create <i>column filters</i>.
/// </summary>
/// <value><c>true</c> by default.</value>
public bool AutoCreateFilters
{
get { return mAutoCreateFilters; }
set { mAutoCreateFilters = value; }
} /// <summary>
/// Gets and sets the <i>filter host</i> to use.
/// </summary>
/// <remarks>
/// The default <i>filter host</i> is an instance of <see cref="DgvFilterHost"/>
/// </remarks> public DgvBaseFilterHost FilterHost
{
get
{
if (mFilterHost == null)
{
// If not provided, use the default FilterHost
FilterHost = new DgvFilterHost();
//FilterHost.AllowDrop = true;
//FilterHost.Popup.MouseDown += FilterHost_MouseDown; }
return mFilterHost;
}
set
{
mFilterHost = value;
// initialize FilterManager to this object
mFilterHost.FilterManager = this;
mFilterHost.Popup.Closed += new ToolStripDropDownClosedEventHandler(Popup_Closed); }
} void oForm_DragEnter(object sender, DragEventArgs e)
{
//当Button被拖拽到WinForm上时候,鼠标效果出现
if ((e.Data.GetDataPresent(typeof(DgvFilterHost))))
{
e.Effect = DragDropEffects.Copy;
}
} void oForm_DragDrop(object sender, DragEventArgs e)
{
//拖放完毕之后,自动生成新控件
//Button btn = new Button();
//btn.Size = Button1.Size;
//btn.Location = this.PointToClient(new Point(e.X, e.Y));
////用这个方法计算出客户端容器界面的X,Y坐标。否则直接使用X,Y是屏幕坐标
//this.Controls.Add(btn);
//btn.Text = "按钮" + count.ToString();
//count = count + 1;
} void FilterHost_MouseDown(object sender, MouseEventArgs e)
{
//左键的话,标志位为true(表示拖拽开始)
if ((e.Button == System.Windows.Forms.MouseButtons.Left))
{
FilterHost.DoDragDrop(FilterHost, DragDropEffects.Copy | DragDropEffects.Move);
//形成拖拽效果,移动+拷贝的组合效果
}
} /// <summary>
/// Gets and sets the DataGridView to which apply filtering capabilities.
/// </summary>
/// <remarks>
/// <para>
/// When a <b>DataGridView</b> is attached, the manager perform the following actions:
/// <ul>
/// <li>it creates a <i>filter host</i>, that is an instance of the <b>DgvFilterHost</b> class. If you previously provided a
/// <i>filter host</i>, this step is skipped.</li>
/// <li>it creates an array of <b>DgvBaseColumnFilter</b>, one per column, and initializes each element to a specialization
/// of <b>DgvBaseColumnFilter</b>. If <see cref="DgvFilterManager.AutoCreateFilters"/> is false, this step is skipped.
/// </li>
/// </ul>
/// </para>
/// <para>
/// You can force a specific <i>column filter</i> for a certain column, intervening in this process through the events
/// <see cref="DgvFilterManager.ColumnFilterAdding"/> and <see cref="DgvFilterManager.ColumnFilterAdded"/>. You can also intervene, after the entire process, replacing
/// a <i>column filter</i> instance in the array with another instance you created.
/// </para>
/// </remarks>
public DataGridView DataGridView
{
get
{
return mDataGridView;
}
set
{
mDataGridView = value;
mColumnFilterList = new List<DgvBaseColumnFilter>(mDataGridView.Columns.Count);
FindDataView();
mDataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
mDataGridView.CellMouseClick += new DataGridViewCellMouseEventHandler(mDataGridView_CellMouseClick);
mDataGridView.CellPainting += new DataGridViewCellPaintingEventHandler(mDataGridView_CellPainting);
mDataGridView.ColumnAdded += new DataGridViewColumnEventHandler(mDataGridView_ColumnAdded);
mDataGridView.ColumnRemoved += new DataGridViewColumnEventHandler(mDataGridView_ColumnRemoved);
if (mDataGridView == null) return;
foreach (DataGridViewColumn c in mDataGridView.Columns)
{
mColumnFilterList.Add(null);
CreateColumnFilter(c);
}
}
} /// <summary>
/// Gets and sets developer provided filter expression. This expression
/// will be "merged" with end-user created filters.
/// </summary>
/// <value>The base filter.</value> public string BaseFilter
{
get { return mBaseFilter; }
set { mBaseFilter = value; RebuildFilter(); }
} /// <summary>
/// Gets or sets the <i>column filter</i> control related to the ColumnIndex
/// </summary>
/// <param name="ColumnIndex">The index of the <b>DataGridView</b> column</param>
/// <returns>the <b>DgvBaseColumnFilter</b> related to the <b>DataGridView</b> column</returns>
/// <remarks>
/// This indexer allow you to get and set the <i>column filter</i> instance for the column.
/// You can set one of the standard <i>column filter</i> implementation or an instance
/// of your own <b>DgvBaseFilterColumn</b> specialization.
/// </remarks>
public DgvBaseColumnFilter this[int ColumnIndex]
{
get { return mColumnFilterList[ColumnIndex]; }
set
{
mColumnFilterList[ColumnIndex] = value;
value.Init(this, FilterHost, mDataGridView.Columns[ColumnIndex], mBoundDataView);
}
} /// <summary>
/// Gets or sets the <i>column filter</i> control related to the ColumnName
/// </summary>
/// <param name="ColumnName">The name of the <b>DataGridView</b> column</param>
/// <returns>the DgvBaseColumnFilter related to the <b>DataGridView</b> column</returns>
/// <remarks>
/// This indexer allow you to get and set the <i>column filter</i> instance for the column.
/// You can set one of the standard <i>column filter</i> implementation or an instance
/// of your own <b>DgvBaseFilterColumn</b> specialization.
/// </remarks>
public DgvBaseColumnFilter this[string ColumnName]
{
get { return mColumnFilterList[mDataGridView.Columns[ColumnName].Index]; }
set
{
this[mDataGridView.Columns[ColumnName].Index] = value;
}
} #endregion #region DATAGRIDVIEW EVENT HANDLERS private void mDataGridView_ColumnRemoved(object sender, DataGridViewColumnEventArgs e)
{
mColumnFilterList.RemoveAt(e.Column.Index);
} private void mDataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
{
FindDataView();
mColumnFilterList.Insert(e.Column.Index, null);
CreateColumnFilter(e.Column);
} #region 新增修改代码 Edit By yangxiaojun System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Resource)); /// <summary>
/// Shows the popup when user right-clicks a column header
/// </summary>
/// <param name="sender">The event source.</param>
/// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellMouseEventArgs"/> instance containing the event data.</param>
protected virtual void mDataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{ //var oForm = mDataGridView.FindForm();
//oForm.AllowDrop = true;
//oForm.DragDrop += oForm_DragDrop;
//oForm.DragEnter += oForm_DragEnter;
if (e.Button == MouseButtons.Right && e.RowIndex == - && e.ColumnIndex > -)
{
if (oMenuStrip == null)
{
oMenuStrip = new ContextMenuStrip();
oMenuStrip.Size = new System.Drawing.Size(, );
}
oMenuStrip.Items.Clear();
//0.升序菜单
var oSortClientEnvent = new EventHandler(mMenuStripSort_Click);
var oToolAscding = new MyToolStripMenuItem("升序", ((System.Drawing.Image)(resources.GetObject("ascending"))), oSortClientEnvent);
oToolAscding.Name = "toolscriptmenuitemasc";
oToolAscding.Size = new System.Drawing.Size(, );
oToolAscding.SortKey = this.mDataGridView.Columns[e.ColumnIndex].Name;
oToolAscding.SortDirection = ListSortDirection.Ascending;
oMenuStrip.Items.Add(oToolAscding); //1.降序菜单
var oToolDescending = new MyToolStripMenuItem("降序", ((System.Drawing.Image)(resources.GetObject("descending"))), oSortClientEnvent);
oToolDescending.Name = "toolscriptmenuitemdesc";
oToolDescending.Size = new System.Drawing.Size(, );
oToolDescending.SortKey = this.mDataGridView.Columns[e.ColumnIndex].Name;
oToolDescending.SortDirection = ListSortDirection.Descending;
oMenuStrip.Items.Add(oToolDescending); //2.分割线
var oSeparator = new System.Windows.Forms.ToolStripSeparator();
oMenuStrip.Items.Add(oSeparator); //3.过滤菜单
var oToolFilter = new MyToolStripMenuItem("过滤...", ((System.Drawing.Image)(resources.GetObject("Filter_Image"))), new EventHandler(mMenuStripFilter_Click));
oToolFilter.ColumnIndex = e.ColumnIndex;
oToolFilter.ColumnName = this.mDataGridView.Columns[e.ColumnIndex].Name;
oMenuStrip.Items.Add(oToolFilter); //4.取消过滤菜单
var oToolCancelFilter = new MyToolStripMenuItem("取消过滤", ((System.Drawing.Image)(resources.GetObject("Filter_Clear_Image"))), new EventHandler(mMenuStripCancelFilter_Click));
oToolCancelFilter.ColumnIndex = e.ColumnIndex;
oToolCancelFilter.ColumnName = this.mDataGridView.Columns[e.ColumnIndex].Name;
oMenuStrip.Items.Add(oToolCancelFilter);
Rectangle r = mDataGridView.GetCellDisplayRectangle(e.ColumnIndex, -, false);
oMenuStrip.Show(mDataGridView, r.X + e.X, r.Y + e.Y);
//ShowPopup(e.ColumnIndex);
}
} //菜单单击排序事件
protected virtual void mMenuStripSort_Click(object sender, EventArgs e)
{
//MessageBox.Show("测试");
var oToolScript = (((MyToolStripMenuItem)sender));
this.mDataGridView.Sort(this.mDataGridView.Columns[oToolScript.SortKey], oToolScript.SortDirection);
} //菜单单击过滤事件
protected virtual void mMenuStripFilter_Click(object sender, EventArgs e)
{
Ewin.Client.Frame.Forms.EwinTaskWindow.ShowTaskWindow("Edit Filter", FilterHost); var oToolScript = (((MyToolStripMenuItem)sender)); if (mColumnFilterList[oToolScript.ColumnIndex] == null) return; // non-data column
SetCurrentFilterIndex(oToolScript.ColumnIndex);
//FilterHost.Popup.Show(mDataGridView, 480, 150); // show the filterhost popup near the column
FilterHost.Popup.Focus();
var lstCols = mDataGridView.Columns;
var lstDataSource = new List<object>();
foreach (DataGridViewColumn oCol in lstCols)
{
var oColHeadName = oCol.HeaderText.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var comboitem = new { Value = oCol.Name, Text = oColHeadName[] };
lstDataSource.Add(comboitem);
//lstDataSource.Add(oCol.Name);
}
FilterHost.ComboBoxColumns.DataSource = lstDataSource;
FilterHost.ComboBoxColumns.DisplayMember = "Text";
FilterHost.ComboBoxColumns.ValueMember = "Value";
FilterHost.ComboBoxColumns.SelectedValueChanged += ComboBoxColumns_SelectedValueChanged;
FilterHost.ComboBoxColumns.SelectedValue = oToolScript.ColumnName; //显示过滤表达式
SetFilterExpression();
} //取消过滤菜单事件
protected virtual void mMenuStripCancelFilter_Click(object sender, EventArgs e)
{
var oToolScript = (((MyToolStripMenuItem)sender)); //0.指定当前过滤列索引
if (mColumnFilterList[oToolScript.ColumnIndex] == null) return; // non-data column
SetCurrentFilterIndex(oToolScript.ColumnIndex); //1.使当前过滤列失效,即Active=false;
ActivateFilter(false);
} //删除过滤条件图标的点击事件
private void oPicBox_Click(object sender, EventArgs e)
{
//1.根据过来字段找到过滤字段索引
var oPicBox = (EwinImgButton)sender;
var iFilterIndex = GetFilterIndexByFilterName(oPicBox.Tag.ToString());
if (iFilterIndex == -) return;
//2.设置当前过滤索引
SetCurrentFilterIndex(iFilterIndex); //3.将当前过滤列的Active设为false
ActivateFilter(false); //4.设置过滤表达式
SetFilterExpression();
} //选择列的选择事件
protected virtual void ComboBoxColumns_SelectedValueChanged(object sender, EventArgs e)
{
var oSelectedValue = ((ComboBox)sender).SelectedValue.ToString();
var iFilterIndex = GetFilterIndexByFilterName(oSelectedValue);
if (iFilterIndex == -) return;
SetCurrentFilterIndex(iFilterIndex);
} //根据过滤列的名称得到过滤列的列索引
private int GetFilterIndexByFilterName(string strFilterName)
{
int iRes = -;
var lstCols = mDataGridView.Columns;
foreach (DataGridViewColumn oCol in lstCols)
{
if (oCol.Name == strFilterName ||oCol.HeaderText.Contains(strFilterName))
{
if (mColumnFilterList[oCol.Index] == null) return -; // non-data column
iRes = oCol.Index;
break;
}
} return iRes;
} //设置当前过滤索引
private void SetCurrentFilterIndex(int iIndex)
{
int OldColumnIndex = mCurrentColumnIndex;
mCurrentColumnIndex = iIndex;
FilterHost.CurrentColumnFilter = mColumnFilterList[iIndex];
try
{
//use "try" because old column could have been removed
mDataGridView.InvalidateCell(OldColumnIndex, -);
}
catch { }
} //显示过滤表达式
public void SetFilterExpression()
{
var arrFilterText = new List<string>();
foreach (DgvBaseColumnFilter CF in mColumnFilterList)
{
if (CF == null) continue;
if (CF.Active && CF.FilterExpression != "")
{
arrFilterText.Add(CF.FilterCaption.Replace("\n", " ").Replace("<> ?", "<> NULL").Replace("= ?", "= NULL"));
}
} //var strRowFilterText = mBoundDataView.RowFilter.Contains("1=1 AND") ? mBoundDataView.RowFilter.Replace("1=1 AND", string.Empty) : mBoundDataView.RowFilter;
//var arrFilterText = strRowFilterText.Split(new string[] { " AND " }, StringSplitOptions.RemoveEmptyEntries);
var y = ;
//0.先清空表达式再重新绘制控件
FilterHost.PanelFilterText.Controls.Clear();
var panelFilterText = new EwinPanel();
panelFilterText.AutoScroll = true;
panelFilterText.HorizontalScrollbar = true;
panelFilterText.HorizontalScrollbarBarColor = true;
panelFilterText.HorizontalScrollbarHighlightOnWheel = false;
panelFilterText.HorizontalScrollbarSize = ;
panelFilterText.Location = new System.Drawing.Point(, );
panelFilterText.Name = "panelFilterText1";
panelFilterText.Size = new System.Drawing.Size(, );
panelFilterText.VerticalScrollbar = true;
panelFilterText.VerticalScrollbarBarColor = true;
panelFilterText.VerticalScrollbarHighlightOnWheel = false;
panelFilterText.VerticalScrollbarSize = ;
panelFilterText.ShowBorder = false;
foreach (var strText in arrFilterText)
{
//1.新增panel
var oPanelText = new EwinPanel();
oPanelText.Name = "oPanelText" + y;
oPanelText.Location = new System.Drawing.Point(, y);
oPanelText.Size = new System.Drawing.Size(, );
oPanelText.ShowBorder = false; //2.向panel里面新增显示表达式的label
var oLabelText = new EwinLabel();
oLabelText.Cursor = Cursors.Hand;
oLabelText.ForeColor = Color.BlueViolet;
oLabelText.AutoSize = true;
oLabelText.Location = new System.Drawing.Point(, );
oLabelText.Name = "label_filtertext" + y;
oLabelText.Text = strText.Trim().Trim(new char[] { '(', ')' });
oLabelText.Size = new System.Drawing.Size(oLabelText.Text.Length * , ); //3.向panel里面新增删除图标
var oPicBox = new EwinImgButton();
oPicBox.Image = ((System.Drawing.Image)(resources.GetObject("Close_tab")));
oPicBox.Cursor = Cursors.Hand;
oPicBox.Location = new Point(oLabelText.Width + , );
oPicBox.Size = new System.Drawing.Size(, );
var otooltip = new System.Windows.Forms.ToolTip();
otooltip.SetToolTip(oPicBox, "删除过滤条件");
oPicBox.Click += oPicBox_Click;
oPicBox.Tag = oLabelText.Text.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[];
oPanelText.Controls.Add(oPicBox);
oPanelText.Controls.Add(oLabelText);
y = y + ;
panelFilterText.Controls.Add(oPanelText);
//FilterHost.PanelFilterText.Controls.Add(oPanelText);
}
FilterHost.PanelFilterText.Controls.Add(panelFilterText);
panelFilterText.Invalidate();
}
#endregion //Based on filters state, call the appropriate protected paint helpers
private void mDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex != -) return; //skip if it is not the header row //1.绘制e.RowIndex == -1 && e.ColumnIndex == -1处的过滤图标
//Cell Origin
if (e.RowIndex == - && e.ColumnIndex == - && mFilterIsActive)
{
OnFilteredGridPaint(sender, e);
return;
} //2.如果过滤框显示,绘制过滤列表头的边框
//if (FilterHost.Popup.Visible)
//{
// OnHighlightedColumnPaint(sender, e);
//} //3.绘制过滤列表头的样式
if (e.ColumnIndex == -) return;
if (mColumnFilterList[e.ColumnIndex] != null && mColumnFilterList[e.ColumnIndex].Active)
{
OnFilteredColumnPaint(sender, e);
}
} /// <summary>
/// Paints a funnel icon in the cell origin when some column is filtered.
/// </summary>
/// <param name="sender">The sender</param>
/// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellPaintingEventArgs"/> instance containing the event data.</param>
/// <remarks>
/// Override this method to provide your own painting
/// </remarks>
protected virtual void OnFilteredGridPaint(object sender, DataGridViewCellPaintingEventArgs e)
{
e.Graphics.FillRectangle(Brushes.White, e.CellBounds);
e.Paint(e.CellBounds, e.PaintParts & ~DataGridViewPaintParts.Background);
Rectangle r = new Rectangle(e.CellBounds.X + , e.CellBounds.Y + , e.CellBounds.Width - , e.CellBounds.Height - );
e.Graphics.DrawImage(FunnelPicture, (e.CellBounds.Width - FunnelPicture.Width) / , (e.CellBounds.Height - FunnelPicture.Height) / , FunnelPicture.Width, FunnelPicture.Height);
e.Graphics.DrawRectangle(Pens.Black, r); e.Handled = true; //e.Paint(e.CellBounds, DataGridViewPaintParts.All);
//e.Graphics.DrawImage(FunnelPicture, (e.CellBounds.Width - FunnelPicture.Width) / 2, (e.CellBounds.Height - FunnelPicture.Height) / 2, FunnelPicture.Width, FunnelPicture.Height);
//e.Handled = true;
} /// <summary>
/// Performs customized column header painting when the popup is visibile.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellPaintingEventArgs"/> instance containing the event data.</param>
/// <remarks>
/// Override this method to provide your own painting
/// </remarks>
protected virtual void OnHighlightedColumnPaint(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex != mCurrentColumnIndex || e.RowIndex != -) return;
e.Paint(e.CellBounds, DataGridViewPaintParts.All);
Rectangle r = new Rectangle(e.CellBounds.X + , e.CellBounds.Y + , e.CellBounds.Width - , e.CellBounds.Height - );
e.Graphics.DrawRectangle(Pens.Yellow, r);
e.Handled = true;
} /// <summary>
/// Performs customized column header painting when the column is filtered.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellPaintingEventArgs"/> instance containing the event data.</param>
/// <remarks>
/// Override this method to provide your own painting
/// </remarks>
protected virtual void OnFilteredColumnPaint(object sender, DataGridViewCellPaintingEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Orange, e.CellBounds);
e.Paint(e.CellBounds, e.PaintParts & ~DataGridViewPaintParts.Background);
Rectangle r = new Rectangle(e.CellBounds.X + , e.CellBounds.Y + , e.CellBounds.Width - , e.CellBounds.Height - );
e.Graphics.DrawRectangle(Pens.Orange, r);
e.Handled = true; } #endregion #region FILTERHOST MANAGING //Forces column header repaint when popup is closed, cleaning customized painting performed by OnHighlightedColumnPaint
private void Popup_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
mDataGridView.InvalidateCell(mCurrentColumnIndex, -); // Force header repaint (to hide the selection yellow frame)
} /// <summary>
/// Shows the popup.
/// </summary>
/// <param name="ColumnIndex">Index of the column.</param>
public void ShowPopup(int ColumnIndex)
{
if (mColumnFilterList[ColumnIndex] == null) return; // non-data column
int OldColumnIndex = mCurrentColumnIndex;
mCurrentColumnIndex = ColumnIndex;
Rectangle r = mDataGridView.GetCellDisplayRectangle(ColumnIndex, -, false); // get the header size info
FilterHost.CurrentColumnFilter = mColumnFilterList[ColumnIndex];
try
{
//use "try" because old column could have been removed
mDataGridView.InvalidateCell(OldColumnIndex, -);
}
catch { }
ColumnFilterEventArgs e = new ColumnFilterEventArgs(mDataGridView.Columns[ColumnIndex], mColumnFilterList[ColumnIndex]);
if (PopupShowing != null) PopupShowing(this, e);
if (!e.Handled) FilterHost.Popup.Show(mDataGridView, r.X + r.Width - , r.Y - ); // show the filterhost popup near the column
FilterHost.Popup.Focus(); mDataGridView.InvalidateCell(mCurrentColumnIndex, -); // Force header repaint (to show a selection yellow frame) } #endregion #region COLUMN FILTERS MANAGING /// <summary>
/// Activates / Deactivates the filter for the column specified by ColumnIndex.
/// </summary>
/// <param name="Active">The active state to set</param>
/// <param name="ColumnIndex">Index of the column.</param>
public void ActivateFilter(bool Active, int ColumnIndex)
{
this[ColumnIndex].Active = Active;
RebuildFilter();
} /// <summary>
/// Activates / Deactivates the filter for the column specified by ColumnName.
/// </summary>
/// <param name="Active">The active state to set</param>
/// <param name="ColumnName">Name of the column.</param>
public void ActivateFilter(bool Active, string ColumnName)
{
this[ColumnName].Active = Active;
RebuildFilter();
} /// <summary>
/// Activates / Deactivates the filter for the current, that is last right-clicked, column.
/// </summary>
/// <param name="Active">The active state to set</param>
public void ActivateFilter(bool Active)
{
if (mCurrentColumnIndex == -) return;
this[mCurrentColumnIndex].Active = Active;
if (Active) this[mCurrentColumnIndex].FilterExpressionBuild();
RebuildFilter();
} /// <summary>
/// Activates / Deactivates all filters.
/// </summary>
/// <param name="Active">The active state to set</param>
public void ActivateAllFilters(bool Active)
{
foreach (DgvBaseColumnFilter CF in mColumnFilterList)
{
if (CF == null) continue;
CF.Active = Active;
if (Active) CF.FilterExpressionBuild();
}
RebuildFilter();
} /// <summary>
/// Rebuilds the whole filter expression.
/// </summary>
/// <remarks>
/// The whole filter expression is the conjunction of each <i>column filter</i> and the <see cref="BaseFilter"/>.
/// Call this method to refresh and apply the whole filter expression.
/// </remarks>
public void RebuildFilter()
{
mFilterIsActive = false;
string Filter = "";
foreach (DgvBaseColumnFilter CF in mColumnFilterList)
{
if (CF == null) continue;
if (CF.Active && CF.FilterExpression != "")
{
Filter += " AND (" + CF.FilterExpression + ")";
CF.DataGridViewColumn.HeaderText = CF.FilterCaption;
}
else
{
CF.DataGridViewColumn.HeaderText = CF.OriginalDataGridViewColumnHeaderText;
} }
if (Filter != "")
{
mFilterIsActive = true;
Filter = (mBaseFilter == "") ? "1=1 " + Filter : mBaseFilter + " " + Filter;
}
else
Filter = mBaseFilter; // Apply the filter only if any changes occurred
try
{
if (mBindingSource != null)
{
if (mBindingSource.Filter != Filter) mBindingSource.Filter = Filter;
}
else
{
if (mBoundDataView.RowFilter != Filter) mBoundDataView.RowFilter = Filter;
}
}
catch { Console.WriteLine("Invalid filter: " + Filter); } } #endregion #region HELPERS // Checks if the DataGridView is data bound and the data source finally resolves to a DataView.
private void FindDataView()
{
mBindingSource = null;
object DataSource = mDataGridView.DataSource;
string DataMember = mDataGridView.DataMember; string ExceptionMsg = "DataGridViewFilter can only work with bound DataGridView. The DataSource must be a DataSet, a DataTable, a DataView or a BindingSource which is bound to a DataSet, a DataTable or a DataView "; while (!(DataSource is DataView))
{ if (DataSource == null)
{
return;
} if (DataSource is BindingSource)
{
mBindingSource = (BindingSource)DataSource;
DataMember = ((BindingSource)DataSource).DataMember;
DataSource = ((BindingSource)DataSource).DataSource;
continue;
}
if (DataSource is DataSet)
{
DataSource = ((DataSet)DataSource).Tables[DataMember];
DataMember = "";
continue;
}
if (DataSource is DataTable)
{
DataSource = ((DataTable)DataSource).DefaultView;
break;
}
if (DataSource is IList)
{
var oTable = Fill(DataSource);
DataSource = oTable == null ? new DataView() : oTable.DefaultView;
break;
}
//other types are not allowed
throw new Exception(ExceptionMsg);
}
mBoundDataView = (DataView)DataSource;
} private DataTable Fill(object obj)
{
if (!(obj is IList))
{
return null;
}
var objlist = obj as IList;
if (objlist == null || objlist.Count <= )
{
return null;
}
var tType = objlist[];
DataTable dt = new DataTable(tType.GetType().Name);
DataColumn column;
DataRow row;
System.Reflection.PropertyInfo[] myPropertyInfo = tType.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var t in objlist)
{
if (t == null)
{
continue;
}
row = dt.NewRow();
for (int i = , j = myPropertyInfo.Length; i < j; i++)
{
System.Reflection.PropertyInfo pi = myPropertyInfo[i];
string name = pi.Name;
if (dt.Columns[name] == null)
{
var coltype = pi.PropertyType;
if (coltype.Name == "Nullable`1")
{
//coltype = typeof(System.DBNull);
column = new DataColumn(name);
}
else
{
column = new DataColumn(name, coltype);
}
dt.Columns.Add(column);
}
row[name] = pi.GetValue(t, null);
}
dt.Rows.Add(row);
}
return dt;
} //The funnel picture
private static Image mFilterPicture; /// <summary>
/// Gets a funnel picture.
/// </summary>
public static Image FunnelPicture
{
get
{
if (mFilterPicture == null)
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DgvFilterHost));
mFilterPicture = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
}
return mFilterPicture;
}
} private void CreateColumnFilter(DataGridViewColumn c)
{
if (mBoundDataView == null) return;
if (!mAutoCreateFilters) return;
//Raise the event about column filter creation
ColumnFilterEventArgs e = new ColumnFilterEventArgs(c, null);
if (ColumnFilterAdding != null) ColumnFilterAdding(this, e);
//if not provided, by an event handler, proceed with standard filter creation
if (e.ColumnFilter == null)
{
Type DataType = null;
if (c.DataPropertyName != "")
{
DataType = mBoundDataView.Table.Columns[c.DataPropertyName].DataType; switch (c.GetType().Name)
{
case "DataGridViewComboBoxColumn":
e.ColumnFilter = new DgvComboBoxColumnFilter();
break;
case "DataGridViewCheckBoxColumn":
e.ColumnFilter = new DgvCheckBoxColumnFilter();
break;
case "DataGridViewTextBoxColumn":
if (DataType == typeof(DateTime))
{
e.ColumnFilter = new DgvDateColumnFilter();
}
else
e.ColumnFilter = new DgvTextBoxColumnFilter();
break;
}
}
}
mColumnFilterList[c.Index] = e.ColumnFilter;
if (e.ColumnFilter != null)
{ // == null when non-data column
if (ColumnFilterAdded != null) ColumnFilterAdded(this, e);
e.ColumnFilter.Init(this, FilterHost, c, mBoundDataView);
}
} #endregion }
}

2、DgvBaseFilterHost这个用户控件作为弹出过滤框的基类,代码如下:

public class DgvBaseFilterHost : UserControl {

        #region EVENTS

        /// <summary>
/// Occurs when the current visible <i>column filter</i> is changed.
/// </summary>
public event EventHandler CurrentColumnFilterChanged; #endregion #region PRIVATE FIELDS private ToolStripDropDown mPopup;
private DgvFilterManager mFilterManager;
private DgvBaseColumnFilter mCurrentColumnFilter = null;
private Size mSizeDifference; #endregion #region PROPERTIES /// <summary>
/// Return the effective area to which <i>column filters</i> will be added.
/// </summary>
public virtual Control FilterClientArea { get { return this; } } public virtual ComboBox ComboBoxColumns { get; set; } public virtual Panel PanelFilterText { set; get; } /// <summary>
/// Gets the <b>ToolStripDropDown</b> object used to popup the <i>filter host</i>
/// </summary>
public ToolStripDropDown Popup
{
get {
if (mPopup==null) {
mPopup = new ToolStripDropDown();
ToolStripControlHost ControlHost = new ToolStripControlHost(this);
ControlHost.Padding = Padding.Empty;
ControlHost.Margin = Padding.Empty;
ControlHost.AutoSize = false;
mPopup.Padding = Padding.Empty;
mPopup.Items.Add(ControlHost);
mPopup.Region = this.Region;
}
return mPopup;
}
} /// <summary>
/// Gets or sets the <i>filter manger</i>
/// </summary>
public DgvFilterManager FilterManager {
set { mFilterManager = value; }
get { return mFilterManager; }
} /// <summary>
/// Gets or sets the currently visibile <i>column filter</i> control
/// </summary>
public DgvBaseColumnFilter CurrentColumnFilter {
get { return mCurrentColumnFilter; }
set {
// Called once: store the original size difference of the filterhost and the filterClientArea
if (mSizeDifference == Size.Empty) {
mSizeDifference = System.Drawing.Size.Subtract(this.Size, FilterClientArea.Size);
this.MinimumSize = this.Size;
}
if (mCurrentColumnFilter != null) mCurrentColumnFilter.Visible = false;
mCurrentColumnFilter = value;
DoAutoFit();
if (CurrentColumnFilterChanged != null) {
EventArgs e = new EventArgs();
CurrentColumnFilterChanged(this, e);
}
mCurrentColumnFilter.Visible = true;
}
} /// <summary>
/// Gets the original size difference of the <i>filter host</i> and the <see cref="DgvBaseFilterHost.FilterClientArea"/>.
/// </summary>
public Size SizeDifference {
get { return mSizeDifference; }
} #endregion #region HELPERS /// <summary>
/// Performs growing / shrinking of the <i>filter host</i> to best fit the current visibile <i>column filter</i>.
/// </summary>
/// <remarks>
/// Ovverride this method to provide your own resize logic.
/// </remarks>
protected virtual void DoAutoFit() {
Size NewHostSize = Size.Add(mSizeDifference, mCurrentColumnFilter.Size);
NewHostSize.Width = Math.Max(NewHostSize.Width, this.MinimumSize.Width);
NewHostSize.Height= Math.Max(NewHostSize.Height, this.MinimumSize.Height);
this.Size = NewHostSize; FilterClientArea.Size = Size.Subtract(NewHostSize, mSizeDifference);
AlignFilter();
} /// <summary>
/// Aligns the <i>column filter</i> into the filter client area.
/// </summary>
/// <remarks>
/// Ovverride this method to provide your own alignment logic.
/// </remarks>
protected void AlignFilter() {
int x = ; // VFilterAlignmentType.Left:
int y = ; // HFilterAlignmentType.Top:
switch (mCurrentColumnFilter.VFilterAlignment){
case VFilterAlignment.Right:
x = FilterClientArea.Width - mCurrentColumnFilter.Width;
break;
case VFilterAlignment.Center:
x = (FilterClientArea.Width - mCurrentColumnFilter.Width) / ;
break;
} switch (mCurrentColumnFilter.HFilterAlignment) {
case HFilterAlignment.Bottom:
y = FilterClientArea.Height - mCurrentColumnFilter.Height;
break;
case HFilterAlignment.Middle:
y = (FilterClientArea.Height - mCurrentColumnFilter.Height) / ;
break;
}
//mCurrentColumnFilter.Location = new Point(x, y); mCurrentColumnFilter.Location = new Point(, );
} /// <summary>
/// Returns a region based on the transparency color of a bitmap.
/// </summary>
/// <param name="bitmap">The bitmap.</param>
/// <param name="transparencyColor">The transparency color.</param>
/// <returns>A region</returns>
public static Region BitmapToRegion(Bitmap bitmap, Color transparencyColor) {
if (bitmap == null)
throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!"); int height = bitmap.Height;
int width = bitmap.Width; GraphicsPath path = new GraphicsPath(); for (int j = ; j < height; j++)
for (int i = ; i < width; i++) {
if (bitmap.GetPixel(i, j) == transparencyColor)
continue; int x0 = i; while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
i++; path.AddRectangle(new Rectangle(x0, j, i - x0, ));
} Region region = new Region(path);
path.Dispose();
return region;
} /// <summary>
/// Registers the a combo box.
/// </summary>
/// <param name="comboBox">The combo box.</param>
/// <remarks>
/// When the user clicks on an <b>ComboBox</b> item that is outside of the
/// host area, this cause an unwanted closing of the <i>filter host</i>.
/// If you use a <b>ComboBox</b> in a customized <i>column filter</i>,
/// be sure to call this method in your filter intitialitazion code.
/// </remarks>
public void RegisterComboBox (ComboBox comboBox){
comboBox.DropDown += new EventHandler(onDropDown);
comboBox.DropDownClosed += new EventHandler(onDropDownClosed);
} private void onDropDown(object sender, EventArgs e)
{
//this.Popup.AutoClose = false;
} private void onDropDownClosed(object sender, EventArgs e)
{
//this.Popup.AutoClose = true;
} #endregion }

3、DgvBaseFilterHost的实现类

[ToolboxItem(false)]
public partial class DgvFilterHost : DgvBaseFilterHost { /// <summary>
/// Initializes a new instance of the <see cref="DgvFilterHost"/> class.
/// </summary>
public DgvFilterHost() {
InitializeComponent();
this.CurrentColumnFilterChanged += new EventHandler(DgvFilterHost_CurrentColumnFilterChanged);
//不用点击非弹出框就关闭
this.Popup.AutoClose = false;
} void DgvFilterHost_CurrentColumnFilterChanged(object sender, EventArgs e) {
//lblColumnName.Text = CurrentColumnFilter.OriginalDataGridViewColumnHeaderText;
} /// <summary>
/// Return the effective area to which the <i>column filters</i> will be added.
/// </summary>
/// <value></value>
public override Control FilterClientArea {
get {
return this.panelFilterArea;
}
} public override ComboBox ComboBoxColumns
{
get
{
return this.comboBox_Cols;
}
//set
//{
// this.comboBox_Cols = value;
//}
} public override Panel PanelFilterText
{
get
{
return this.panelFilterText;
}
//set
//{
// this.panelFilterText = value;
//}
} private void tsOK_Click(object sender, EventArgs e) {
//FilterManager.ActivateFilter(true);
FilterManager.RebuildFilter();
//this.Popup.Close();
this.FindForm().Hide();
} private void tsRemove_Click(object sender, EventArgs e) {
FilterManager.ActivateFilter(false);
this.Popup.Close();
} private void tsRemoveAll_Click(object sender, EventArgs e) {
FilterManager.ActivateAllFilters(false);
FilterManager.SetFilterExpression();
//this.Popup.Close();
} private void pictureBox2_Click(object sender, EventArgs e)
{
this.Popup.Close();
} private void pictureBox3_Click(object sender, EventArgs e)
{
//0.激活当前过滤列并过滤
FilterManager.ActivateFilter(true); //1.重新绑定过滤条件
FilterManager.SetFilterExpression();
} }

4、DgvBaseColumnFilter这个用户控件作为过滤列选项的基类,代码如下:

/// <summary>
/// Specifies how the <i>column filter</i> control is horizontally aligned inside the <i>filter host</i>.
/// </summary>
public enum HFilterAlignment { Top, Bottom, Middle } /// <summary>
/// Specifies how the <i>column filter</i> control is vertically aligned inside the <i>filter host</i>.
/// </summary>
public enum VFilterAlignment { Left, Right, Center } /// <summary>
/// The base class from which to derive effective <i>column filter</i> classes
/// </summary>
/// <remarks>
/// The purpose of a <i>column filter</i> control is to contain visual elements allowing the end user to construct a filter.
/// When inheriting from it, you can work just like creating any other user control.
/// This class is a derivation of <b>UserControl</b> and provide functionalities to
/// cooperate with DgvFilterManager.
/// <para>
/// NOTE:
/// This class must be intended as an abstract class. However, declaring it as abstract,
/// would generate errors whitin the designer when designing derived classes.
/// </para>
/// <para>
/// You should override <see cref="DgvBaseColumnFilter.OnFilterExpressionBuilding"/> to provide a filter expression construction
/// logic and to set the values of the <see cref="DgvBaseColumnFilter.FilterExpression"/> and <see cref="DgvBaseColumnFilter.FilterCaption"/> properties.
/// </para>
/// </remarks>
public class DgvBaseColumnFilter : UserControl { #region EVENTS /// <summary>
/// Occurs before the filter expression is about to be built.
/// </summary>
public event CancelEventHandler FilterExpressionBuilding; /// <summary>
/// Occurs when the filter column is about to be initialized.
/// </summary>
public event CancelEventHandler FilterInitializing; #endregion #region PRIVATE FIELDS private VFilterAlignment mVFilterAlignment = VFilterAlignment.Center;
private HFilterAlignment mHFilterAlignment = HFilterAlignment.Middle;
private DgvBaseFilterHost mFilterHost;
private DgvFilterManager mFilterManager;
private DataGridViewColumn mDataGridViewColumn;
private DataView mBoundDataView;
private Type mColumnDataType;
private string mOriginalDataGridViewColumnHeaderText;
private bool mActive;
private bool mFilterApplySoon = true; private string mFilterExpression = "";
private string mFilterCaption = ""; #endregion #region PROPERTIES /// <summary>
/// Gets or sets a value indicating whether filter apply soon after a user performs some changes.
/// </summary>
/// <value><c>true</c> (default) if to apply soon; otherwise, <c>false</c>.</value>
public bool FilterApplySoon {
get { return mFilterApplySoon; }
set { mFilterApplySoon = value; }
} /// <summary>
/// Gets and sets the filter expression.
/// </summary>
/// <remarks>
/// It's the filter expression on the column. Its value is used by the <see cref="DgvFilterManager"/> to build the whole filter expression.
/// In inherited class, set its value in the override of <see cref="DgvBaseColumnFilter.OnFilterExpressionBuilding"/>.
/// The filter expression must follow the rules of the DataView <see cref="System.Data.DataView.RowFilter"/> property.
/// </remarks>
public string FilterExpression {
get { return mFilterExpression; }
set { mFilterExpression = value; }
} /// <summary>
/// Gets and sets the caption to show in the column header when the filter is active.
/// </summary>
/// <remarks>
/// Represents the caption to show in the column header when the filter is active.
/// In inherited class, set its value in the override of <see cref="DgvBaseColumnFilter.OnFilterExpressionBuilding"/>.
/// </remarks>
public string FilterCaption {
get { return ( (mActive && mFilterExpression!="") ? mFilterCaption : mOriginalDataGridViewColumnHeaderText) ; }
set { mFilterCaption = value; }
} /// <summary>
/// Gets or sets a value indicating whether the filter is active.
/// </summary>
/// <value><c>true</c> if active; otherwise, <c>false</c>.</value>
public bool Active {
get { return (mActive); }
set { mActive = value; }
} /// <summary>
/// Specifies how the <i>column filter</i> control is horizontally aligned inside the <i>filter host</i>.
/// </summary>
public HFilterAlignment HFilterAlignment {
get { return mHFilterAlignment; }
set { mHFilterAlignment = value;
}
} /// <summary>
/// Specifies how the <i>column filter</i> control is vertically aligned inside the <i>filter host</i>.
/// </summary>
public VFilterAlignment VFilterAlignment {
get { return mVFilterAlignment; }
set { mVFilterAlignment = value; }
} /// <summary>
/// Gets the <b>DataView</b> acting as the data source of the <b>DataGridView</b> to which this <i>column filter</i> is applied.
/// </summary>
public DataView BoundDataView { get { return mBoundDataView; }} /// <summary>
/// Gets the <i>filter host</i> control in which this <i>column filter</i> is shown.
/// </summary>
public DgvBaseFilterHost FilterHost { get { return mFilterHost; }} /// <summary>
/// Gets the <i>filter manager</i>.
/// </summary>
public DgvFilterManager FilterManager { get { return mFilterManager; }} /// <summary>
/// Gets the <b>DataGridView</b> column to which this <i>column filter</i> is applied.
/// </summary>
/// <value>The data grid view column.</value>
public DataGridViewColumn DataGridViewColumn { get { return mDataGridViewColumn; }} /// <summary>
/// Gets the type of the data bound to the <b>DataGridView</b> column.
/// </summary>
public Type ColumnDataType { get { return mColumnDataType; }} /// <summary>
/// Gets the original <b>DataGridView</b> column header text.
/// </summary>
public string OriginalDataGridViewColumnHeaderText { get { return mOriginalDataGridViewColumnHeaderText; } } #endregion #region FILTER INITIALIZATION, EXPRESSION BUILDING, EVENT MANAGING /// <summary>
/// Called by the <i>filter manager</i>, inits the <i>column filter</i> and raises the FilterInitializing event.
/// </summary>
/// <param name="FilterManager">The <i>filter manager</i>.</param>
/// <param name="FilterHost">The filter host.</param>
/// <param name="gridColumn">The DataGridView column.</param>
/// <param name="boundDataView">The bound data view.</param>
public void Init(DgvFilterManager FilterManager, DgvBaseFilterHost FilterHost, DataGridViewColumn gridColumn,DataView boundDataView){
this.mFilterManager = FilterManager;
this.mFilterHost = FilterHost;
this.mDataGridViewColumn = gridColumn;
this.mBoundDataView = boundDataView;
this.mOriginalDataGridViewColumnHeaderText = gridColumn.HeaderText;
if (gridColumn.DataPropertyName != "")
this.mColumnDataType = boundDataView.Table.Columns[gridColumn.DataPropertyName].DataType;
else
this.mColumnDataType = typeof(string);
FilterHost.FilterClientArea.Controls.Add(this);
FilterHost.Location = new System.Drawing.Point(, );
this.Visible = false;
CancelEventArgs e = new CancelEventArgs(false);
OnFilterInitializing(this, e);
} /// <summary>
/// Raises the <see cref="DgvBaseColumnFilter.FilterInitializing"/> event
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
/// <remarks>
/// When this <i>column filter</i> control is added to the <i>column filters</i> array of the <i>filter manager</i>,
/// the latter calls the <see cref="DgvBaseColumnFilter.Init"/> method which, in turn, calls this method.
/// You can ovverride this method to provide initialization code.
/// </remarks>
protected virtual void OnFilterInitializing(object sender, CancelEventArgs e) {
// Ovverride to add custom init code
if (FilterInitializing != null) FilterInitializing(sender, e);
} /// <summary>
/// Forces the rebuilt of filter expression
/// </summary>
/// <remarks>
/// This method is called by <see cref="DgvFilterManager"/> when popup is closed, to
/// force recreation of the filter expression.
/// </remarks>
public void FilterExpressionBuild() {
CancelEventArgs e = new CancelEventArgs(false);
OnFilterExpressionBuilding(this,e);
} /// <summary>
/// Raises the <see cref="DgvBaseColumnFilter.FilterExpressionBuilding"/> event
/// </summary>
/// <param name="sender">The event source.</param>
/// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
/// <remarks>
/// Override <b>OnFilterExpressionBuilding</b> to provide a filter expression construction
/// logic and to set the values of the <see cref="DgvBaseColumnFilter.FilterExpression"/> and <see cref="DgvBaseColumnFilter.FilterCaption"/> properties.
/// The <see cref="DgvFilterManager"/> will use these properties in constructing the whole filter expression and to change the header text of the filtered column.
/// </remarks>
protected virtual void OnFilterExpressionBuilding(object sender,CancelEventArgs e) {
if (FilterExpressionBuilding != null) FilterExpressionBuilding(sender, e);
} #endregion #region HELPERS /// <summary>
/// Escapes a string to be suitable for filter expression.
/// </summary>
/// <param name="s">The string to escape.</param>
/// <returns>The escaped string</returns>
public static string StringEscape(string s){
char[] sarray = s.ToCharArray();
StringBuilder sb = new StringBuilder(s.Length * );
foreach (char c in sarray) {
switch (c){
case '%': case '*': case '[': case ']':
sb.Append("[" + c + "]");
break;
case '\'':
sb.Append("''");
break;
default:
sb.Append(c);
break;
}
}
return sb.ToString();
} /// <summary>
/// Returns the string representation of the passed value, based on target type.
/// </summary>
/// <param name="value">The value to be formatted.</param>
/// <param name="targetType">The target type.</param>
/// <returns>The string representation of the passed value</returns>
public static string FormatValue(object value,Type targetType){
if (targetType == typeof(string)) return "'" + value.ToString() + "'";
try {
value = Convert.ChangeType(value, targetType);
} catch { return ""; } if (targetType == typeof(bool)) return ((bool)value) ? "" : "";
if (targetType == typeof(DateTime)) return "'" + ((DateTime)value).ToString("yyyy'-'MM'-'dd") +"'";
//Numeric types
return ((IFormattable)value).ToString(null, NumberFormatInfo.InvariantInfo);
} /// <summary>
/// Returns a null condition string to be used in filter expression.
/// </summary>
/// <param name="DataColumnName">Name of the data column.</param>
/// <returns>A string to be used in the filter expression representing a null condition</returns>
public static string GetNullCondition (string DataColumnName){
return "ISNULL(CONVERT(" + DataColumnName+ ",'System.String'),'NULLVALUE') = 'NULLVALUE'";
} /// <summary>
/// Returns a not null condition string to be used in filter expression.
/// </summary>
/// <param name="DataColumnName">Name of the data column.</param>
/// <returns>A string to be used in the filter expression representing a not null condition</returns>
public static string GetNotNullCondition (string DataColumnName){
return "ISNULL(CONVERT(" + DataColumnName+ ",'System.String'),'NULLVALUE') <> 'NULLVALUE'";
} #endregion }

5、DgvBaseColumnFilter的实现类有多个,分别定义不同类型的过滤列:

5.1、Textbox原型的过滤子类

5.2、ComboBox原型的过滤子类

应博友要求,附上源码。源码下载

源码可能和贴图上面不太一样,是因为贴图上面是和我们项目样式相关的,项目太大,无法贴上来。源码是测试功能用的,原来从别处下载下来改写了下,但功能和贴图上面是差不多的,有兴趣的可以看看。

上一篇:oracle里如何将两个日期的时间差返回**时**分的格式


下一篇:IDEA 使用Mybatis效率飞起来的必备工具:MybatisCodeHelperPro 最新破解版,亲测可用!