开源DataGridView扩展(6) 简单实现checkbox行选级联。

开源DataGridView扩展(6) 简单实现checkbox行选级联。_第1张图片

开源DataGridView扩展(6) 简单实现checkbox行选级联。_第2张图片

                                                        < 他们有差别吗?>

 

一、需求

       为甚有这种想法呢,那是来自需求的压迫,可怜我们这些苦逼的程序猿及攻城狮们只能彻夜难眠、苦思冥想、几十亿个脑细胞兄弟们前赴后继最终才能取得芝麻点大的胜利,好吧我们来看需求。

1. 现在要一个表格,表格的第一列是一个选中操作的复选框,要求能再复选框选中时,也对此行进行行选。

二、分析设计

      First,让我们来看下,GridView中本身带了哪些我们能用的方法:

      a. 自身带有checkbox列,我们也自定义了我们的扩展checkbox列。

      b. 表格本身具有行选属性。

      c. 表格本身带有多行选择属性。

      好吧到然后了,通过利用这些已有的属性我们简单实现之,在checkbox的选中事件中进行行选操作。然后就实现啦。。。

     

      Wait,这样真的就这么简单的实现了,让我们仔细想想是不是哪里不对劲啊?

      Yeah,问题又来了:

      1) 表格的列是在用的时候才设计checkbox列的,那么怎样才能让这些功能在DataGridView中实现呢?

      2) 我们知道checkbox不一定只是为了选中某一行,它还是一个状态的控件,比如他要代表是否,我们不能同意而论啊?

      Ok,来吧,让我们重新的整理一下:首先我们采用绑定的方式来设置标志复选框,即指定多个复选框的其中一个为标志行选的复选框。其次,在CellPainting事件中选中该标志复选框为选中的行或者设置行单元格颜色等。然后就没有然后了。。。

三、实现

      首先,设置一个标志列名,如果此属性设置为checkbox的列名,则表示该checkbox列是标志列。

   1:     private string m_FlagColumnName = string.Empty;
   2:          [Category("ut"), Browsable(true), Description("选中标志选中列的一项"), Localizable(true)]
   3:          [DefaultValue(null), Editor(typeof(DataGridViewFlagRowEditor), typeof(System.Drawing.Design.UITypeEditor))]
   4:          public string FlagColumnName
   5:          {
   6:              get
   7:              {
   8:                  return m_FlagColumnName;
   9:              }
  10:              set
  11:              {
  12:                  m_FlagColumnName = value;
  13:                  if (!string.IsNullOrEmpty(m_FlagColumnName))
  14:                      base.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
  15:              }
  16:          }

      在CellPainting里处理吧:

   1:    DataGridViewCheckBoxCellEx paintCell;
   2:          protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
   3:          {
   4:              if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
   5:              if (!this.Columns.Contains(FlagColumnName)) return;
   6:              paintCell = this.Rows[e.RowIndex].Cells[FlagColumnName] as DataGridViewCheckBoxCellEx;
   7:              if (paintCell != null && paintCell.Checked)
   8:              {
   9:                  //e.CellStyle.BackColor = e.CellStyle.SelectionBackColor;
  10:                  this.Rows[e.RowIndex].Selected = true;
  11:              }
  12:   
  13:              base.OnCellPainting(e);
  14:          }

      其实,最重点的在哪里?我们如何将FlagColumnName设置与标志checkbox的名字一致呢?手动?不至于吧,所以这里用到了Editor

 

   1:  namespace DataGridViewEx.DataGridViewExs.EditorEx
   2:  {
   3:        /// <summary>
   4:      ///DataGridViewEx中的RowFlag标识设计器
   5:      /// </summary>
   6:      public class DataGridViewFlagRowEditor : UITypeEditor
   7:      {
   8:          const string NullValue = "(None)";
   9:          private IWindowsFormsEditorService m_editorService = null;
  10:          public DataGridViewFlagRowEditor()
  11:              : base()
  12:          {
  13:          }
  14:   
  15:          public override object EditValue(System.ComponentModel.ITypeDescriptorContext context,
  16:              IServiceProvider provider, object value)
  17:          {
  18:              if (context != null && context.Instance != null && provider != null)
  19:              {
  20:                  m_editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
  21:                  DataGridViewCheckBoxColumnEx column = null;
  22:                  List<string> columnNameList = new List<string>();
  23:   
  24:                  foreach (IComponent c in context.Container.Components)
  25:                  {
  26:                      if (c is DataGridViewCheckBoxColumnEx)
  27:                      {
  28:                          column = (DataGridViewCheckBoxColumnEx)c;
  29:                          columnNameList.Add(column.Name);
  30:                      }
  31:                  }
  32:                  if (columnNameList.Count > 0 && m_editorService != null)
  33:                  {
  34:                      int i = 0;
  35:                      string selectValue = (string)value;
  36:                      ListBox listBox = new ListBox();
  37:                      listBox.SelectedIndexChanged += new EventHandler(listBox_SelectedIndexChanged);
  38:                      listBox.Items.Add(NullValue);
  39:                      foreach (string name in columnNameList)
  40:                      {
  41:                          i = listBox.Items.Add(name);
  42:                          if (name == selectValue)
  43:                              listBox.SelectedIndex = i;
  44:                      }
  45:                      m_editorService.DropDownControl(listBox);
  46:                      if (listBox.SelectedItem != null)
  47:                      {
  48:                          if (listBox.SelectedItem.ToString() == NullValue)
  49:                              return string.Empty;
  50:                          return listBox.SelectedItem;
  51:                      }
  52:                  }
  53:              }
  54:              return value;
  55:          }
  56:   
  57:          private void listBox_SelectedIndexChanged(object sender, EventArgs e)
  58:          {
  59:              if (m_editorService != null)
  60:                  m_editorService.CloseDropDown();
  61:          }
  62:   
  63:          /// <summary>
  64:          /// Gets the editor style used by the EditValue method.
  65:          /// </summary>
  66:          /// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
  67:          /// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None</returns>
  68:          public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
  69:          {
  70:              if (context != null && context.Instance != null)
  71:              {
  72:                  return UITypeEditorEditStyle.DropDown;
  73:              }
  74:              return base.GetEditStyle(context);
  75:          }
  76:      }
  77:  }

 

 

这里的Editor是Winform中自定义控件的一个很好的功能,即UI设计器的扩展。这里通过Editor使得我们的FlagColumnName通过设计器中寻找到可选的所有的DataGridViewCheckboxColumnEx供用户选择:

开源DataGridView扩展(6) 简单实现checkbox行选级联。_第3张图片

四、源码及演示程序下载。

演示程序: FlagCheckboxColumn.rar

开源项目:http://sourceforge.net/p/datagridviewex/code-0/3/tree/trunk/DataGridViewEx/

你可能感兴趣的:(datagridview)