我們見過Excel中的數據過濾功能,可以通過點擊表頭上的下拉列表來實現數據的過濾,這個功能很實用,省去了我們需要在程序中單獨設計數據的查詢過濾模塊,功能直接依賴于數據綁定控件DataGridView。先來看看Excel中的數據過濾功能。

要想在DataGridView中實現類似于Excel的這種功能其實也并非難事。來看看msdn上的一篇文章,上面有詳細的介紹,不過目前只有全英文的版本。。里面提供的下載示例我這里也可以提供一份:
文章講了很多有關如何實現數據過濾的知識,如果你有耐心可以通讀一遍,應該能有不小的收獲。其實這里面的原理就是我 們需要自定義一種DataGridViewColumn,它能支持用戶通過點擊表頭上的下拉列表來實現DataGridView的數據過濾。自定義的 DataGridViewColumn可以繼承自現有的DataGridViewTextBoxColumn類型,另外還需要自定義一個繼承自 DataGridViewColumnHeaderCell的類型,它負責在DataGridView表頭上呈現一個下拉列表,并完成數據過濾的選擇功 能。下載上面的DataGridViewAutoFilter.zip壓縮包,將里面對應編程語言中的 DataGridViewAutoFilterColumnHeaderCell.cs和 DataGridAutoFilterTextBoxColumn.cs兩個文件加入到你的工程中。然后需要重新定義DataGridView中的列,如 果你是手動指定DataGridView的列,則需要在窗體的Designer.cs文件中手動修改與DataGridView列相關的代碼;或者你也可 以通過程序動態指定DataGridView的列。將需要顯示數據過濾的列的類型指定為 DataGridViewAutoFilterTextBoxColumn類型。另外在綁定DataGridView數據源時必須使用 BindingSource而不能使用如DataTable之類的普通數據源,這一點非常重要!在后面的代碼展示中你將會看到為什么要這么做。
這里是具體的例子:
1 public Form1()
2 {
3 InitializeComponent();
4
5 // create sequence
6 Item[] items = new Item[] { new Book{Id = 1, Price = 13.50,
Genre = "Comedy", Author = "Jim Bob"},
7 new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "John Fox"},
8 new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Phil Funk"},
9 new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Eddie Jones"}};
10
11
12 var query = from i in items
13 orderby i.Price
14 select i;
15
16 DataTable table = query.CopyToDataTable();
17 BindingSource source = new BindingSource();
18 source.DataSource = table;
19
20 foreach (DataColumn col in table.Columns)
21 {
22 DataGridViewAutoFilterTextBoxColumn commonColumn =
new DataGridViewAutoFilterTextBoxColumn();
23 commonColumn.DataPropertyName = col.ColumnName;
24 commonColumn.HeaderText = col.ColumnName;
25 commonColumn.Resizable = DataGridViewTriState.True;
26 this.dataGridView1.Columns.Add(commonColumn);
27 }
28
29 this.dataGridView1.DataSource = source;
30 }
代碼中的第16行將LINQ的查詢結果轉換成了DataTable對象,相關內容大家可以看我的另一篇文章“”。 另外代碼中將DataGridView的所有列的類型指定成了DataGridViewAutoFilterTextBoxColumn,使其能夠支持自 定義的數據過濾功能。好了,現在運行你的應用程序,將會看到表頭上有下拉列表的小箭頭,點擊它并選擇下拉列表中的項便可實現DataGridView數據 的排序。是不是很酷啊?不過這里還有一個小問題,那就是用戶如何知道我當前選擇了哪個列的數據過濾,界面是不是應該給出相應的數據過濾信息呢?我們可以在 窗體的StatusStrip控件中添加一些Label標簽用來顯示這些信息:
1. 顯示用戶當前選擇了多少行。這個需要將DataGridView的SelectionMode屬性設置成行選擇模式即FullRowSelect。
2. 顯示當前DataGridView一共有多少行。
3. 顯示Filter的信息及應用數據過濾之后的總行數。
4. 添加一個按鈕或鏈接用于移除當前的Filter。
來看看具體的實現代碼及程序運行時的效果:
1 private void dataGridView1_SelectionChanged(object sender, EventArgs e)
2 {
3 int iCount = this.dataGridView1.SelectedRows.Count;
4 this.toolStripStatus_SelectedRows.Text = string.Format( "{0} row{1} selected", iCount.ToString(), iCount > 1 ? "s" : "");
5 }
6
7 private void dataGridView1_DataBindingComplete
(object sender, DataGridViewBindingCompleteEventArgs e)
8 {
9 BindingSource data = this.dataGridView1.DataSource as BindingSource;
10 if (data == null || data.DataSource == null)
11 {
12 return;
13 }
14
15 /* Show total records number*/
16 // Retrieve the unfiltered row count by
17 // temporarily unfiltering the data.
18 data.RaiseListChangedEvents = false;
19 String oldFilter = data.Filter;
20 data.Filter = null;
21 int iTotalNum = data.Count;
22 this.toolStripStatus_Total.Text = string.Format("Total of {0} record{1}.",
iTotalNum.ToString(), iTotalNum > 1 ? "s" : "");
23 data.Filter = oldFilter;
24 data.RaiseListChangedEvents = true;
25
26 /* Show filter information.*/
27 int iFilterNum = data.Count;
28 string filter = data.Filter;
29 if (String.IsNullOrEmpty(filter))
30 {
31 this.toolStripStatus_Separator2.Visible = false;
32 this.toolStripStatus_Filter.Visible = false;
33 this.toolStripStatus_ShowAll.Visible = false;
34 }
35 else
36 {
37 this.toolStripStatus_Separator2.Visible = true;
38 this.toolStripStatus_Filter.Visible = true;
39 this.toolStripStatus_ShowAll.Visible = true;
40 this.toolStripStatus_Filter.Text =string.Format("{0} record{1} found.",
iFilterNum.ToString(), iFilterNum > 1 ? "s" : "");
41 this.toolStripStatus_Filter.Text += " (Filter: " + filter + ")";
42 }
43 }
44
45 private void toolStripStatus_ShowAll_Click(object sender, EventArgs e)
46 {
47 DataGridViewAutoFilterColumnHeaderCell.RemoveFilter(this.dataGridView1);
48 }

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。
標簽:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園