C#自定义DataGridViewColumn显示TreeView

所属分类: 软件编程 / C#教程 阅读数: 84
收藏 0 赞 0 分享

我们可以自定义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 的全部叙述,希望大家喜欢。

更多精彩内容其他人还在看

c#开发word批量转pdf源码分享

已经安装有Office环境,借助一些简单的代码即可实现批量Word转PDF,看下面的实例源码吧
收藏 0 赞 0 分享

c# xml API操作的小例子

这篇文章主要介绍了c# xml API操作的小例子,有需要的朋友可以参考一下
收藏 0 赞 0 分享

c#唯一值渲染实例代码

这篇文章主要介绍了c#唯一值渲染实例代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

淘宝IP地址库采集器c#代码

这篇文章主要介绍了淘宝IP地址库采集器c#代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C#在后台运行操作(BackgroundWorker用法)示例分享

BackgroundWorker类允许在单独的专用线程上运行操作。如果需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题,下面看示例
收藏 0 赞 0 分享

c#文本加密程序代码示例

这是一个加密软件,但只限于文本加密,加了窗口控件的滑动效果,详细看下面的代码
收藏 0 赞 0 分享

c#生成站点地图(SiteMapPath)文件示例程序

这篇文章主要介绍了c#生成站点地图(SiteMapPath)文件的示例,大家参考使用
收藏 0 赞 0 分享

C# 键盘Enter键取代Tab键实现代码

这篇文章主要介绍了C# 键盘Enter键取代Tab键实现代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C# WinForm导出Excel方法介绍

在.NET应用中,导出Excel是很常见的需求,导出Excel报表大致有以下三种方式:Office PIA,文件流和NPOI开源库,本文只介绍前两种方式
收藏 0 赞 0 分享

C#串口通信程序实例详解

在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports,创建C#串口通信程序的具体实现是如何的呢?让我们开始吧
收藏 0 赞 0 分享
查看更多