图:效果图
一、 设计初衷
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下载:DataGridCellFormatter@DataGridViewEx.rar
开源地址 :http://sourceforge.net/p/datagridviewex/code-0/3/tree/trunk/DataGridViewEx/
出处:http://gxjiang.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。