开源DataGridView扩展(3) 单元格格式化器的设计 DataGridCellFormatter

r1

图:效果图

 

一、 设计初衷

1. 有没有想过当你的表格中的某些数据需要分类时该如何做?

2. 有没有想过当表格中的数据根据某一状态来启用/禁用某个按钮?

3. 有没有想过为了突出某一些数据,所以加颜色来区分?

4. 总得来说,就是如何根据数据来设置行或单元格的样式?

二、 设计实现

      通过以上几个疑问,最终也归结为一点:如何根据数据来设置行或单元格的样式? 其实这个问题,我也纠结了一段时间,后来再详细的查找尝试后,不经意间发现在DataGridView中有一个CellFormatting事件,这样的话就为我的解决方案提供了基础。

1. 思考之一,对于单元格的格式化,由于是基于内容来改变样式,所以可以为列(Column)来注册一个格式化器,因为列的内容类型是一致的。

2. 思考之二,为了能提供在封装之后的样式的灵活改变,就应该把格式化器的注册开放到外部,所以以委托形式来注册。

综上考虑,最终设计了这么一个类:

   1:   public class DataGridCellFormatter : IDisposable
   2:      {
   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/

源码下载  :ver4.0_带上CellFormatter的源码.rar


posted @ 2012-05-02 22:40  江心逐浪  阅读(3005)  评论(9编辑  收藏  举报