| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6766 人关注过本帖, 1 人收藏
标题:在DataGridView控件上实现列标头象Excel带数据筛选功能
只看楼主 加入收藏
不说也罢
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:39
帖 子:1481
专家分:4989
注 册:2007-10-7
结帖率:100%
收藏(1)
已结贴  问题点数:100 回复次数:15 
在DataGridView控件上实现列标头象Excel带数据筛选功能
程序代码:
'近日有本论坛网友问:DataGridView如何实现列标头带数据筛选功能,就象Excel高级筛选功能一样
'今晚正好闲着没事,加之以前也没用到过这个需求,所以就写了个模拟功能,供各位坛友酌情参考。
' 2008 环境
'新建一个项目后,只需在Form1中拉一个DataGridView,一个ComboBox,然后将下面代码复制粘贴即可,其它什么也不用做

Public Class Form1
    Dim SelectedCol As Integer = 0, IsFindit As Boolean = True
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        DataGridView1.ColumnCount = 6
        DataGridView1.Rows.Add(10)
        DataGridView1.AllowUserToAddRows = False
        For i As Integer = 0 To Me.DataGridView1.Columns.Count - 1
            Me.DataGridView1.Columns(i).SortMode = DataGridViewColumnSortMode.NotSortable
        Next
        '以下所有代码只是为了添加演试数据需要
        For i = 0 To DataGridView1.RowCount - 1
            For j As Integer = 0 To DataGridView1.ColumnCount - 1
                DataGridView1.Columns(j).HeaderText = "" & j.ToString & ""
                DataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
                DataGridView1.Rows(i).Cells(j).Value = (i + 5) * (j + 2)
            Next
            If i Mod 2 = 0 Then
                DataGridView1.Rows(i).Cells(2).Value = "ds"
            Else
                DataGridView1.Rows(i).Cells(3).Value = "测试一下"
            End If
        Next
    End Sub

    Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) _
        Handles DataGridView1.ColumnHeaderMouseClick

        '这里是模拟EXCEL排序的关键部分
        SelectedCol = e.ColumnIndex
        Dim range As New System.Drawing.Rectangle
        Dim dLeft, dTop As Double
        range = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
        dLeft = range.Left + DataGridView1.Left
        dTop = range.Top + DataGridView1.Top
        ComboBox1.SetBounds(dLeft, dTop, range.Width, range.Height)
        ComboBox1.Items.Clear()
        ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
        ComboBox1.Items.Add("请选择排序")
        For i As Integer = 0 To DataGridView1.RowCount - 1
            IsFindit = False
            For j = 0 To ComboBox1.Items.Count - 1
                If ComboBox1.Items(j).ToString = DataGridView1.Rows(i).Cells(e.ColumnIndex).Value.ToString Then
                    IsFindit = True
                    j = ComboBox1.Items.Count
                End If
            Next
            If Not IsFindit Then ComboBox1.Items.Add(DataGridView1.Rows(i).Cells(e.ColumnIndex).Value.ToString)
        Next
        ComboBox1.SelectedIndex = 0
        ComboBox1.Show()
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        '这里是筛选功能
        Select Case ComboBox1.SelectedIndex
            Case 0
                For i As Integer = 0 To DataGridView1.RowCount - 1
                    DataGridView1.Rows(i).Visible = True
                Next
            Case Else
                For i As Integer = 0 To DataGridView1.RowCount - 1
                    If DataGridView1.Rows(i).Cells(SelectedCol).Value.ToString <> ComboBox1.SelectedItem.ToString Then
                        DataGridView1.Rows(i).Visible = False
                    Else
                        DataGridView1.Rows(i).Visible = True
                    End If
                Next
        End Select
        If ComboBox1.SelectedIndex = 0 Then ComboBox1.Hide()
    End Sub
End Class

请有需要的朋友尽管拿去,也可以尝试加强其功能
搜索更多相关主题的帖子: Excel 
2013-05-31 20:07
不说也罢
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:39
帖 子:1481
专家分:4989
注 册:2007-10-7
收藏
得分:0 
看贴请跟贴哦。嘻嘻哈哈

下面是这个例子的运行截图:
图片附件: 游客没有浏览图片的权限,请 登录注册

上图为启动窗体时截图
图片附件: 游客没有浏览图片的权限,请 登录注册

上图为单击列标头的截图
图片附件: 游客没有浏览图片的权限,请 登录注册

上图为在下拉框中选择筛选条件
图片附件: 游客没有浏览图片的权限,请 登录注册

条件筛选后的截图

===================================================
讨厌C#的行尾的小尾巴;和一对大括号{ }
===================================================
2013-05-31 20:13
ZMGTCDY
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:51
专家分:115
注 册:2012-10-5
收藏
得分:100 
非常感谢“不说也罢”给出的具体操作代码。虽然对应数据库操作能否适用我还不知道,不过其中很多亮点还是值得学习。再次感谢!
2013-06-02 10:51
ZMGTCDY
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:51
专家分:115
注 册:2012-10-5
收藏
得分:0 
回复 2楼 不说也罢
这几天一直用你的代码对数据库进行测试。
2013-06-02 10:59
不说也罢
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:39
帖 子:1481
专家分:4989
注 册:2007-10-7
收藏
得分:0 
呵呵,互相学习。

===================================================
讨厌C#的行尾的小尾巴;和一对大括号{ }
===================================================
2013-06-03 12:41
ZMGTCDY
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:51
专家分:115
注 册:2012-10-5
收藏
得分:0 
回复 5楼 不说也罢
SelectedCol = e.ColumnIndex
        Dim range As New System.Drawing.Rectangle
        Dim dLeft, dTop As Double
        range = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
        dLeft = range.Left + DataGridView1.Left
        dTop = range.Top + DataGridView1.Top
        ComboBox1.SetBounds(dLeft, dTop, range.Width, range.Height)
之前我的想法和你差不多,只是ComboBox放在表头上是死的不能动,让我非常苦恼。我都想放弃这种方法了,您写的上述代码能让ComboBox控件可以
随DataGridView列宽移动,非常神奇!高手就是高手在下佩服。再次感谢!
2013-06-03 15:37
不说也罢
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:39
帖 子:1481
专家分:4989
注 册:2007-10-7
收藏
得分:0 
以下是引用ZMGTCDY在2013-6-3 15:37:43的发言:

 SelectedCol = e.ColumnIndex
        Dim range As New System.Drawing.Rectangle
        Dim dLeft, dTop As Double
        range = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
        dLeft = range.Left + DataGridView1.Left
        dTop = range.Top + DataGridView1.Top
        ComboBox1.SetBounds(dLeft, dTop, range.Width, range.Height)
之前我的想法和你差不多,只是ComboBox放在表头上是死的不能动,让我非常苦恼。我都想放弃这种方法了,您写的上述代码能让ComboBox控件可以
随DataGridView列宽移动,非常神奇!高手就是高手在下佩服。再次感谢!
如果能够帮到你,我也很高兴。
因为我一直没有需要到这个功能,你问了,正遇上有空闲时间,所以就写了这个例子。
你也可以尝试在这个基础上增加更多的功能,比如,在可见的情况下调整列宽,ComboBox还不能同步改变大小,再比如,EXCEL可以多选筛选条件的,这个代码还要再修改才能实现。总之,我这个例子仅仅是个思路而已。
的人并不多,大家多交流。

===================================================
讨厌C#的行尾的小尾巴;和一对大括号{ }
===================================================
2013-06-03 17:43
ZMGTCDY
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:51
专家分:115
注 册:2012-10-5
收藏
得分:0 
回复 7楼 不说也罢
图片附件: 游客没有浏览图片的权限,请 登录注册

刚刚看了你的留言很高兴,和你的观点不谋而合。这几天我一直做这件事,就是复合筛选问题。本来我已经成功了,但是又出了新问题。
就是窗体加载的时候,RichTextBox中的内容出现闪烁,原因是
Handles 子类ComboBox.SelectedIndexChanged
 Me.记事本TableAdapter.FillBy12(Me.ZMKJDataSet.记事本, 分类ComboBox1.Text, 子类ComboBox1.Text, 标题ComboBox1.Text)
在窗体加载过程中,将以上数据都浏览了一遍(个人观点不知道对不对)。现在还没有满意的办法解决。
不知道大师有什么办法解决这个问题。

2013-06-11 17:07
不说也罢
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:39
帖 子:1481
专家分:4989
注 册:2007-10-7
收藏
得分:0 
你这样子的筛选与你当初提问的模仿EXCEL筛选功能其实是有区别的。
这个功能是针对已赋值的datagridview中的数据进行筛选

Me.记事本TableAdapter.FillBy12(Me.ZMKJDataSet.记事本, 分类ComboBox1.Text, 子类ComboBox1.Text, 标题ComboBox1.Text)
这个代码是什么意思?TableAdapter对象有FillBy12这个方法吗?


===================================================
讨厌C#的行尾的小尾巴;和一对大括号{ }
===================================================
2013-06-11 18:44
xjb_test
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2012-5-18
收藏
得分:0 
楼主,不知道为什么我按你方法操作了一下。不成功
2013-07-12 14:39
快速回复:在DataGridView控件上实现列标头象Excel带数据筛选功能
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023589 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved