转:http://www.cnblogs.com/jaxu/archive/2011/08/04/2127365.html

我们见过Excel中的数据过滤功能,可以通过点击表头上的下拉列表来实现数据的过滤,这个功能很实用,省去了我们需要在程序中单独设计数据的查询过滤模块,功能直接依赖于数据绑定控件DataGridView。先来看看Excel中的数据过滤功能。

 要想在DataGridView中实现类似于Excel的这种功能其实也并非难事。来看看msdn上的一篇文章,上面有详细的介绍,不过目前只有全英文的版本。http://msdn.microsoft.com/en-us/library/aa480727.aspx。里面提供的下载示例我这里也可以提供一份:DataGridViewAutoFilter.zip

  文章讲了很多有关如何实现数据过滤的知识,如果你有耐心可以通读一遍,应该能有不小的收获。其实这里面的原理就是我们需要自定义一种DataGridViewColumn,它能支持用户通过点击表头上的下拉列表来实现DataGridView的数据过滤。自定义的DataGridViewColumn可以继承自现有的DataGridViewTextBoxColumn类型,另外还需要自定义一个继承自DataGridViewColumnHeaderCell的类型,它负责在DataGridView表头上呈现一个下拉列表,并完成数据过滤的选择功能。下载上面的DataGridViewAutoFilter.zip压缩包,将里面对应编程语言中的DataGridViewAutoFilterColumnHeaderCell.cs和DataGridAutoFilterTextBoxColumn.cs两个文件加入到你的工程中。然后需要重新定义DataGridView中的列,如果你是手动指定DataGridView的列,则需要在窗体的Designer.cs文件中手动修改与DataGridView列相关的代码;或者你也可以通过程序动态指定DataGridView的列。将需要显示数据过滤的列的类型指定为DataGridViewAutoFilterTextBoxColumn类型。另外在绑定DataGridView数据源时必须使用BindingSource而不能使用如DataTable之类的普通数据源,这一点非常重要!在后面的代码展示中你将会看到为什么要这么做。

  这里是具体的例子:

public Form1()
{InitializeComponent();// create sequence Item[] items = new Item[] { new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Jim Bob"}, new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "John Fox"},  new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Phil Funk"},new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Eddie Jones"}};var query = from i in itemsorderby i.Priceselect i;DataTable table = query.CopyToDataTable();BindingSource source = new BindingSource();source.DataSource = table;foreach (DataColumn col in table.Columns){DataGridViewAutoFilterTextBoxColumn commonColumn = new DataGridViewAutoFilterTextBoxColumn();commonColumn.DataPropertyName = col.ColumnName;commonColumn.HeaderText = col.ColumnName;commonColumn.Resizable = DataGridViewTriState.True;this.dataGridView1.Columns.Add(commonColumn);}            this.dataGridView1.DataSource = source;
}

代码中的第16行将LINQ的查询结果转换成了DataTable对象,相关内容大家可以看我的另一篇文章“如何将LINQ查询到的结果由匿名类型var转换成DataTable对象”。另外代码中将DataGridView的所有列的类型指定成了DataGridViewAutoFilterTextBoxColumn,使其能够支持自定义的数据过滤功能。好了,现在运行你的应用程序,将会看到表头上有下拉列表的小箭头,点击它并选择下拉列表中的项便可实现DataGridView数据的排序。是不是很酷啊?不过这里还有一个小问题,那就是用户如何知道我当前选择了哪个列的数据过滤,界面是不是应该给出相应的数据过滤信息呢?我们可以在窗体的StatusStrip控件中添加一些Label标签用来显示这些信息:

  1. 显示用户当前选择了多少行。这个需要将DataGridView的SelectionMode属性设置成行选择模式即FullRowSelect。

  2. 显示当前DataGridView一共有多少行。

  3. 显示Filter的信息及应用数据过滤之后的总行数。

  4. 添加一个按钮或链接用于移除当前的Filter。

  来看看具体的实现代码及程序运行时的效果:

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{int iCount = this.dataGridView1.SelectedRows.Count;this.toolStripStatus_SelectedRows.Text = string.Format("{0} row{1} selected", iCount.ToString(), iCount > 1 ? "s" : "");
}private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{BindingSource data = this.dataGridView1.DataSource as BindingSource;if (data == null || data.DataSource == null){return;}/* Show total records number*/// Retrieve the unfiltered row count by // temporarily unfiltering the data.data.RaiseListChangedEvents = false;String oldFilter = data.Filter;data.Filter = null;int iTotalNum = data.Count;this.toolStripStatus_Total.Text = string.Format("Total of {0} record{1}.", iTotalNum.ToString(), iTotalNum > 1 ? "s" : "");data.Filter = oldFilter;data.RaiseListChangedEvents = true;/* Show filter information.*/int iFilterNum = data.Count;string filter = data.Filter;if (String.IsNullOrEmpty(filter)){this.toolStripStatus_Separator2.Visible = false;this.toolStripStatus_Filter.Visible = false;this.toolStripStatus_ShowAll.Visible = false;}else{this.toolStripStatus_Separator2.Visible = true;this.toolStripStatus_Filter.Visible = true;this.toolStripStatus_ShowAll.Visible = true;this.toolStripStatus_Filter.Text = string.Format("{0} record{1} found.", iFilterNum.ToString(), iFilterNum > 1 ? "s" : "");this.toolStripStatus_Filter.Text += " (Filter: " + filter + ")";}
}private void toolStripStatus_ShowAll_Click(object sender, EventArgs e)
{DataGridViewAutoFilterColumnHeaderCell.RemoveFilter(this.dataGridView1);
}

1. 当前用户选择的总行数。

  2. DataGridView中一共有多少行。

  3. Filter的信息及使用Filter之后的数据行数。

  4. 用于移除Filter的链接。

  代码中一共是三个事件,dataGridView1_SelectionChanged事件用于在DataGridView行被选择时触发,用来更新StatusStrip中当前用户选择的总行数;dataGridView1_DataBindingComplete事件在DataGridView数据完成绑定时触发,用来更新StatusStrip中Filter的信息及使用Filter之后的数据行数,以及DataGridView的数据总行数,注意其中将BindingSource的RaiseListChangedEvents设置为false以取得DataGridView数据源中的真实数据行数,之后再将其设置为true以获取到Filter的相关信息;toolStripStatus_ShowAll_Click事件为用户点击Show All链接时触发,用于移除DataGridView中的Filter。

这里是完整的代码:

http://pan.baidu.com/s/1eRZiw8M

.NET WinForm程序中给DataGridView表头添加下拉列表实现数据过滤相关推荐

  1. C#中Winform程序中如何实现多维表头【不通过第三方报表程序】

    问题:C#中Winform程序中如何实现多维表头. 在网上搜了很多方法,大多数方法对于我这种新手,看的都不是很懂.最后在新浪博客看到了一篇比较易懂的文章:[DataGridView二维表头与合并单元格 ...

  2. 在Winform程序中设置管理员权限及为用户组添加写入权限

    在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限,如果是在操作系统里面,我们可以设置运行程序以管理员身 ...

  3. (转)在Winform程序中设置管理员权限及为用户组添加写入权限

    本文转载自:http://www.cnblogs.com/wuhuacong/p/5645172.html 在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行 ...

  4. 在winform程序中启动wpf窗体

    有时候需要在winform程序中利用wpf的许多优良特性,如何在其中启动wpf窗体呢? 前提:MainWindow.xaml是从别的地方copy到这个项目的,值得注意的是,除了MainWindow.x ...

  5. 转:WinForm程序中两份mdf文件问题的解决方法

    在项目中用程序中嵌入mdf文件的方式来进行SQLServer数据库开发非常方便,用来发布开源项目等很方便,点击就可以运行,免部署,特别是在教学中用起来更加方便,老师不用先将数据库文件detach再发给 ...

  6. 在WinForm程序中嵌入ASP.NET

    现在的流行趋势是桌面程序Web化,Web程序桌面化,呵呵.最终目标就是你中有我,我中有你.例如MSN Explorer就是一个很好的展示,让用户在使用的时候分不清什么时候是在本地什么时候是在网络.而这 ...

  7. 在WinForm程序中嵌入ASP.NET[转]

    在WinForm程序中嵌入ASP.NET 现在的流行趋势是桌面程序Web化,Web程序桌面化,呵呵.最终目标就是你中有我,我中有你.例如MSN Explorer就是一个很好的展示,让用户在使用的时候分 ...

  8. 在C# winform程序中调用WPF写的数学公式编辑器

    由于工作原因,需要在程序中加入数学公式编辑功能,因此在网上找了不少开源数学公式程序.经过比较,最终选择了Math-Editor-master程序(可以在github上搜索此名称). 我的程序(简称主程 ...

  9. Element 中的表格表头添加搜索图标和功能

    Element 中的表格表头添加搜索图标和功能 主要实现 table的slot='header' headerData是表头的循环数组 tableData是表格内容的数组 <template s ...

最新文章

  1. centos中python2.7被覆盖,yum,python重新安装
  2. 重磅消息:Redis 6.0.0 稳定版发布
  3. pytorch自带网络_【方家之言】一篇长文学懂 pytorch
  4. matlab鬼成像,一种基于光计算的可视化计算鬼成像系统及成像方法与流程
  5. android电视盒子解码很慢,电视盒子反应慢又卡原因及解决办法推荐!
  6. 使用snmp4j实现Snmp功能(三)
  7. 窦学计算机基础期末考试,关于新生开学考计算机基础
  8. NodeJs 的安装及配置环境变量
  9. iOS求职之OC面试题完整版---持续更新中...
  10. 对事件循环的一点理解
  11. C++ malloc new 的区别
  12. NodeJS运行时抛出: Error: listen EADDRINUSE :::3000
  13. PPT小图标库及配色网站推荐
  14. Docker镜像分层原理-联合文件系统(UnionFS)
  15. win2012R2无法打开匿名级安全令牌,安装.net 3.5
  16. k37.第十五章 K8s运维篇-Prometheus监控 (三)
  17. MyCAT XA分布式事务
  18. python中使用requests库获取昵图网图片,且正则中re.S的用法
  19. unirech阿里云国际版元宇宙解决方案
  20. 笔谈OpenGL ES(三)

热门文章

  1. (建议收藏)前端面试必问的十六条HTTP网络知识体系
  2. [知乎回答] 前端是否要学习 Node.js?
  3. 我真的哭了,哭过后呢(-)
  4. 云时代架构读后感4--IT架构的本质
  5. 如何抓住重点,系统高效地学习数据结构与算法?
  6. .Net+MySQL组合开发(二) 数据访问篇
  7. mysql 如何用一条SQL将一张表里的数据插入到另一张表 3个例子
  8. matlab 规范,matlab-代码-规范
  9. Anaconda+vscode+pytorch环境搭建
  10. PHP常用工具方法集...