圖:效果圖
一、 設計初衷
1. 有沒有想過當你的表格中的某些數據需要分類時該如何做?
2. 有沒有想過當表格中的數據根據某一狀態來啓用/禁用某個按鈕?
3. 有沒有想過爲了突出某一些數據,所以加顏色來區分?
4. 總得來說,就是如何根據數據來設置行或單元格的樣式?
二、 設計實現
通過以上幾個疑問,最終也歸結爲一點:如何根據數據來設置行或單元格的樣式? 其實這個問題,我也糾結了一段時間,後來再詳細的查找嘗試後,不經意間發現在DataGridView中有一個CellFormatting事件,這樣的話就爲我的解決方案提供了基礎。
1. 思考之一,對於單元格的格式化,由於是基於內容來改變樣式,所以可以爲列(Column)來註冊一個格式化器,因爲列的內容類型是一致的。
2. 思考之二,爲了能提供在封裝之後的樣式的靈活改變,就應該把格式化器的註冊開放到外部,所以以委託形式來註冊。
綜上考慮,最終設計了這麼一個類:
1: public class DataGridCellFormatter : IDisposable2: {
3:
4: /// <summary>5: /// 值與顯示轉換的委託6: /// </summary>7: /// <param name="columnName">當前列名</param>8: /// <param name="value">當前列值</param>9: /// <returns>轉換後的顯示值</returns>10: public delegate void CellFormatDelegate(string columnName, DataGridViewCellFormattingEventArgs value);11:
12: /// <summary>13: /// key:列名,value:註冊的委託14: /// </summary>15: private Dictionary<string, CellFormatDelegate> m_cellFormatters = new Dictionary<string, CellFormatDelegate>();16:
17: /// <summary>18: /// 將列轉換註冊到具體的方法19: /// </summary>20: /// <param name="columnName">註冊列名稱</param>21: /// <param name="formatter">註冊列轉換方法</param>22: public void RegisterFormatter(string columnName, CellFormatDelegate formatter)23: {
24: if (!string.IsNullOrEmpty(columnName) && formatter != null)25: m_cellFormatters[columnName] = formatter;
26: }
27:
28: /// <summary>29: /// 獲取註冊格式化器30: /// </summary>31: /// <param name="columnName"></param>32: public CellFormatDelegate GetRegisterFormatter(string columnName)33: {
34: if (m_cellFormatters.ContainsKey(columnName))35: return m_cellFormatters[columnName];36: return null;37: }
38:
39: /// <summary>40: /// 執行格式化操作41: /// </summary>42: /// <param name="columnName"></param>43: /// <param name="defaultValue"></param>44: public void RunFormatter(string columnName, DataGridViewCellFormattingEventArgs defaultValue)45: {
46: CellFormatDelegate formatter = GetRegisterFormatter(columnName);
47: if (formatter == null) return;48: formatter(columnName, defaultValue);
49: }
50:
51: public void Dispose()52: {
53: if (m_cellFormatters.Count > 0)54: m_cellFormatters.Clear();
55: }
56: }
然後再CellFormatting中把格式化器給Hook到DataGridViewEx上面:
1: protected override void OnCellFormatting(DataGridViewCellFormattingEventArgs e)2: {
3: //Mark:在這裏執行註冊的程序4: this.CellFormatterRegister.RunFormatter(this.Columns[e.ColumnIndex].Name, e);5: base.OnCellFormatting(e);6: }
最後,使用者只要在引用DataGridViewEx的時候,註冊一下想要的列改變就行了:
1: protected void RegisterCellFormatters()2: {
3: this.dataGridViewEx1.CellFormatterRegister.RegisterFormatter("Column5",4: new DataGridCellFormatter.CellFormatDelegate(FormatColumn5));5: this.dataGridViewEx1.CellFormatterRegister.RegisterFormatter("Column4",6: new DataGridCellFormatter.CellFormatDelegate(FormatColumn4));7: }
8:
9: //根據內容改變Column5的文本顏色10: internal void FormatColumn5(string columnName, DataGridViewCellFormattingEventArgs e)11: {
12: if (e.Value.ToString().Contains("5"))13: {
14: e.CellStyle.ForeColor = Color.Green;
15: }
16:
17: if (e.Value.ToString().Contains("3"))18: {
19: e.CellStyle.ForeColor = Color.Red;
20: }
21: }
22:
23: // 根據內容設置自定義按鈕列爲不可用24: internal void FormatColumn4(string columnName, DataGridViewCellFormattingEventArgs e)25: {
26: if (e.Value.ToString().Contains("2"))27: {
28: DataGridViewButtonCellEx cell =
29: this.dataGridViewEx1.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCellEx;30: if (cell != null)31: {
32: cell.Enabled = false;33: }
34: }
35:
36: }
ok,一切都搞定,讓它自動運行吧。
三、 Demo程序和開源源碼
Demo下載:[email protected]
開源地址 :http://sourceforge.net/p/datagridviewex/code-0/3/tree/trunk/DataGridViewEx/
出處:http://gxjiang.cnblogs.com/
文章版權歸本人所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。