首页 > 编程 > C# > 正文

C#自定义DataGridViewColumn显示TreeView

2020-01-24 01:20:19
字体:
来源:转载
供稿:网友

我们可以自定义DataGridView的DataGridViewColumn来实现自定义的列,下面介绍一下如何通过扩展DataGridViewColumn来实现一个TreeViewColumn

1.TreeViewColumn类

 TreeViewColumn继承自DataGridViewColumn,为了动态给TreeViewColumn传入一个TreeView,这里暴露出一个公共属性_root,可以绑定一个初始化的TreeView. 另外需要重写DataGridCell类型的CellTemplate,这里返还一个TreeViewCell(需要自定义) 

 /// <summary>  /// Host TreeView In DataGridView Cell  /// </summary>  public class TreeViewColumn : DataGridViewColumn  {   public TreeViewColumn()    : base(new TreeViewCell())   {   }   [Description("Set TreeView Root in DataGridView Cell"), Category("TreeView")]   public TreeView _root   {    get{return Roots.tree;}    set{Roots.tree=value;}   }   public override DataGridViewCell CellTemplate   {    get    {     return base.CellTemplate;    }    set    {     // Ensure that the cell used for the template is a TreeViewCell.     if (value != null &&      !value.GetType().IsAssignableFrom(typeof(TreeViewCell)))     {      throw new InvalidCastException("Must be a TreeViewCell");     }     base.CellTemplate = value;    }   }  } 

2.TreeViewCell类

    上面TreeViewColumn重写了CellTemplate,返回的就是自定义的TreeViewCell,这里就是具体实现其逻辑。一般来说选择树控件的节点后,返回的是一个文本信息,是文本类型,可以继承DataGridViewTextBoxCell,并重写InitializeEditingControl来进行自定义的DataGridView.EditingControl (编辑控件)。

 public class TreeViewCell : DataGridViewTextBoxCell  {   public TreeViewCell()    : base()   {    //初始设置   }   public override void InitializeEditingControl(int rowIndex, object    initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)   {    // Set the value of the editing control to the current cell value.    base.InitializeEditingControl(rowIndex, initialFormattedValue,     dataGridViewCellStyle);    TreeViewEditingControl ctl =     DataGridView.EditingControl as TreeViewEditingControl;    // Use the default row value when Value property is null.    if (this.Value == null)    {     ctl.SelectedNode =new TreeNode( this.DefaultNewRowValue.ToString());    }    else    {     ctl.SelectedNode = new TreeNode(this.Value.ToString());    }   }   public override Type EditType   {    get    {     // Return the type of the editing control that CalendarCell uses.     return typeof(TreeViewEditingControl);    }   }   public override Type ValueType   {    get    {     // Return the type of the value that CalendarCell contains.     return typeof(String);    }   }   public override object DefaultNewRowValue   {    get    {     // Use the current date and time as the default value.     return "";    }   }  } 

3.TreeViewEditingControl类

  TreeViewEditingControl为编辑控件,当用户编辑TreeViewCell时,显示的为树编辑控件,需要继承TreeView,同时实现IDataGridViewEditingControl接口,实现以下方法:

 public class TreeViewEditingControl : TreeView, IDataGridViewEditingControl  {   DataGridView dataGridView;   private bool valueChanged = false;   int rowIndex;   public TreeViewEditingControl()   {    try    {     //必须加Roots.tree.Nodes[].Clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆     this.Nodes.Add(Roots.tree.Nodes[].Clone() as TreeNode);     this.SelectedNode = this.Nodes[];    }    catch (Exception ex)    {     MessageBox.Show(ex.Message);    }   }   // Implements the IDataGridViewEditingControl.EditingControlFormattedValue    // property.   public object EditingControlFormattedValue   {    get    {     return this.SelectedNode.Text;    }    set    {     if (value is String)     {      try      {       // This will throw an exception of the string is        // null, empty, or not in the format of a date.       this.SelectedNode = new TreeNode((String)value);      }      catch      {       // In the case of an exception, just use the        // default value so we're not left with a null       // value.       this.SelectedNode = new TreeNode("");      }     }    }   }   // Implements the    // IDataGridViewEditingControl.GetEditingControlFormattedValue method.   public object GetEditingControlFormattedValue(    DataGridViewDataErrorContexts context)   {    return EditingControlFormattedValue;   }   // Implements the    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.   public void ApplyCellStyleToEditingControl(    DataGridViewCellStyle dataGridViewCellStyle)   {    this.Font = dataGridViewCellStyle.Font;    this.ForeColor = dataGridViewCellStyle.ForeColor;    this.BackColor = dataGridViewCellStyle.BackColor;   }   // Implements the IDataGridViewEditingControl.EditingControlRowIndex    // property.   public int EditingControlRowIndex   {    get    {     return rowIndex;    }    set    {     rowIndex = value;    }   }   // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey    // method.   public bool EditingControlWantsInputKey(    Keys key, bool dataGridViewWantsInputKey)   {    // Let the TreeViewPicker handle the keys listed.    switch (key & Keys.KeyCode)    {     case Keys.Left:     case Keys.Up:     case Keys.Down:     case Keys.Right:     case Keys.Home:     case Keys.End:     case Keys.PageDown:     case Keys.PageUp:      return true;     default:      return !dataGridViewWantsInputKey;    }   }   // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit    // method.   public void PrepareEditingControlForEdit(bool selectAll)   {    // No preparation needs to be done.   }   // Implements the IDataGridViewEditingControl   // .RepositionEditingControlOnValueChange property.   public bool RepositionEditingControlOnValueChange   {    get    {     return false;    }   }   // Implements the IDataGridViewEditingControl   // .EditingControlDataGridView property.   public DataGridView EditingControlDataGridView   {    get    {     return dataGridView;    }    set    {     dataGridView = value;    }   }   // Implements the IDataGridViewEditingControl   // .EditingControlValueChanged property.   public bool EditingControlValueChanged   {    get    {     return valueChanged;    }    set    {     valueChanged = value;    }   }   // Implements the IDataGridViewEditingControl   // .EditingPanelCursor property.   public Cursor EditingPanelCursor   {    get    {     return base.Cursor;    }   }   protected override void OnAfterExpand(TreeViewEventArgs e)   {    base.OnAfterExpand(e);    this.dataGridView.Columns[this.dataGridView.CurrentCell.ColumnIndex].Width = this.Width+;    this.dataGridView.Rows[this.dataGridView.CurrentCell.RowIndex].Height = this.Height+;   }   protected override void OnAfterSelect(TreeViewEventArgs e)   {    // Notify the DataGridView that the contents of the cell    // have changed.    valueChanged = true;    this.EditingControlDataGridView.NotifyCurrentCellDirty(true);    base.OnAfterSelect(e);   }  } 

  为了在不同类之间传递参数,定义一个全局静态类:

 /// <summary>  /// 静态类的静态属性,用于在不同class间传递参数  /// </summary>  public static class Roots  {   //从前台绑定树  public static TreeView tree = null;  }

完整代码为:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.ComponentModel; namespace Host_Controls_in_Windows_Forms_DataGridView_Cells {  /// <summary>  /// 静态类的静态属性,用于在不同class间传递参数  /// </summary>  public static class Roots  {   //从前台绑定树   public static TreeView tree = null;  }  /// <summary>  /// Host TreeView In DataGridView Cell  /// </summary>  public class TreeViewColumn : DataGridViewColumn  {   public TreeViewColumn()    : base(new TreeViewCell())   {   }   [Description("Set TreeView Root in DataGridView Cell"), Category("TreeView")]   public TreeView _root   {    get{return Roots.tree;}    set{Roots.tree=value;}   }   public override DataGridViewCell CellTemplate   {    get    {     return base.CellTemplate;    }    set    {     // Ensure that the cell used for the template is a TreeViewCell.     if (value != null &&      !value.GetType().IsAssignableFrom(typeof(TreeViewCell)))     {      throw new InvalidCastException("Must be a TreeViewCell");     }     base.CellTemplate = value;    }   }  }  //----------------------------------------------------------------------  public class TreeViewCell : DataGridViewTextBoxCell  {   public TreeViewCell()    : base()   {    //初始设置   }   public override void InitializeEditingControl(int rowIndex, object    initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)   {    // Set the value of the editing control to the current cell value.    base.InitializeEditingControl(rowIndex, initialFormattedValue,     dataGridViewCellStyle);    TreeViewEditingControl ctl =     DataGridView.EditingControl as TreeViewEditingControl;    // Use the default row value when Value property is null.    if (this.Value == null)    {     ctl.SelectedNode =new TreeNode( this.DefaultNewRowValue.ToString());    }    else    {     ctl.SelectedNode = new TreeNode(this.Value.ToString());    }   }   public override Type EditType   {    get    {     // Return the type of the editing control that CalendarCell uses.     return typeof(TreeViewEditingControl);    }   }   public override Type ValueType   {    get    {     // Return the type of the value that CalendarCell contains.     return typeof(String);    }   }   public override object DefaultNewRowValue   {    get    {     // Use the current date and time as the default value.     return "";    }   }  }  //----------------------------------------------------------------- public class TreeViewEditingControl : TreeView, IDataGridViewEditingControl  {   DataGridView dataGridView;   private bool valueChanged = false;   int rowIndex;   public TreeViewEditingControl()   {    try    {     //必须加Roots.tree.Nodes[].Clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆     this.Nodes.Add(Roots.tree.Nodes[].Clone() as TreeNode);     this.SelectedNode = this.Nodes[];    }    catch (Exception ex)    {     MessageBox.Show(ex.Message);    }   }   // Implements the IDataGridViewEditingControl.EditingControlFormattedValue    // property.   public object EditingControlFormattedValue   {    get    {     return this.SelectedNode.Text;    }    set    {     if (value is String)     {      try      {       // This will throw an exception of the string is        // null, empty, or not in the format of a date.       this.SelectedNode = new TreeNode((String)value);      }      catch      {       // In the case of an exception, just use the        // default value so we're not left with a null       // value.       this.SelectedNode = new TreeNode("");      }     }    }   }   // Implements the    // IDataGridViewEditingControl.GetEditingControlFormattedValue method.   public object GetEditingControlFormattedValue(    DataGridViewDataErrorContexts context)   {    return EditingControlFormattedValue;   }   // Implements the    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.   public void ApplyCellStyleToEditingControl(    DataGridViewCellStyle dataGridViewCellStyle)   {    this.Font = dataGridViewCellStyle.Font;    this.ForeColor = dataGridViewCellStyle.ForeColor;    this.BackColor = dataGridViewCellStyle.BackColor;   }   // Implements the IDataGridViewEditingControl.EditingControlRowIndex    // property.   public int EditingControlRowIndex   {    get    {     return rowIndex;    }    set    {     rowIndex = value;    }   }   // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey    // method.   public bool EditingControlWantsInputKey(    Keys key, bool dataGridViewWantsInputKey)   {    // Let the TreeViewPicker handle the keys listed.    switch (key & Keys.KeyCode)    {     case Keys.Left:     case Keys.Up:     case Keys.Down:     case Keys.Right:     case Keys.Home:     case Keys.End:     case Keys.PageDown:     case Keys.PageUp:      return true;     default:      return !dataGridViewWantsInputKey;    }   }   // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit    // method.   public void PrepareEditingControlForEdit(bool selectAll)   {    // No preparation needs to be done.   }   // Implements the IDataGridViewEditingControl   // .RepositionEditingControlOnValueChange property.   public bool RepositionEditingControlOnValueChange   {    get    {     return false;    }   }   // Implements the IDataGridViewEditingControl   // .EditingControlDataGridView property.   public DataGridView EditingControlDataGridView   {    get    {     return dataGridView;    }    set    {     dataGridView = value;    }   }   // Implements the IDataGridViewEditingControl   // .EditingControlValueChanged property.   public bool EditingControlValueChanged   {    get    {     return valueChanged;    }    set    {     valueChanged = value;    }   }   // Implements the IDataGridViewEditingControl   // .EditingPanelCursor property.   public Cursor EditingPanelCursor   {    get    {     return base.Cursor;    }   }   protected override void OnAfterExpand(TreeViewEventArgs e)   {    base.OnAfterExpand(e);    this.dataGridView.Columns[this.dataGridView.CurrentCell.ColumnIndex].Width = this.Width+;    this.dataGridView.Rows[this.dataGridView.CurrentCell.RowIndex].Height = this.Height+;   }   protected override void OnAfterSelect(TreeViewEventArgs e)   {    // Notify the DataGridView that the contents of the cell    // have changed.    valueChanged = true;    this.EditingControlDataGridView.NotifyCurrentCellDirty(true);    base.OnAfterSelect(e);   }  } }

  当编辑无误后,可以在添加列的时候看到TreeViewColumn类型。此类型暴露出一个_root属性,可以绑定外部的一个带数据的TreeView。

  运行代码,单击单元格,进入编辑状态,可以看到如下界面:

以上内容是小编给大家介绍的C#自定义DataGridViewColumn显示TreeView 的全部叙述,希望大家喜欢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表