• C#如何自定义DataGridViewColumn来显示TreeView


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

    1 TreeViewColumn类

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

     1     /// <summary>
     2     /// Host TreeView In DataGridView Cell
     3     /// </summary>
     4    public class TreeViewColumn : DataGridViewColumn
     5     {
     6         public TreeViewColumn()
     7             : base(new TreeViewCell())
     8         {
     9         }
    10         [Description("Set TreeView Root in DataGridView Cell"), Category("TreeView")]
    11         public TreeView _root
    12         {
    13             get{return Roots.tree;}
    14             set{Roots.tree=value;}
    15         }
    16         public override DataGridViewCell CellTemplate
    17         {
    18             get
    19             {
    20                 return base.CellTemplate;
    21             }
    22             set
    23             {
    24                 // Ensure that the cell used for the template is a TreeViewCell.
    25                 if (value != null &&
    26                     !value.GetType().IsAssignableFrom(typeof(TreeViewCell)))
    27                 {
    28                     throw new InvalidCastException("Must be a TreeViewCell");
    29                 }
    30                 base.CellTemplate = value;
    31             }
    32         }
    33     }

    2 TreeViewCell类

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

     1   public class TreeViewCell : DataGridViewTextBoxCell
     2     {
     3 
     4         public TreeViewCell()
     5             : base()
     6         {
     7         
     8             //初始设置
     9         }
    10        
    11         public override void InitializeEditingControl(int rowIndex, object
    12             initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    13         {
    14             // Set the value of the editing control to the current cell value.
    15             base.InitializeEditingControl(rowIndex, initialFormattedValue,
    16                 dataGridViewCellStyle);
    17             TreeViewEditingControl ctl =
    18                 DataGridView.EditingControl as TreeViewEditingControl;
    19             // Use the default row value when Value property is null.
    20             if (this.Value == null)
    21             {
    22 
    23                 ctl.SelectedNode =new TreeNode( this.DefaultNewRowValue.ToString());
    24             }
    25             else
    26             {
    27                 ctl.SelectedNode = new TreeNode(this.Value.ToString());
    28             }
    29         }
    30 
    31         public override Type EditType
    32         {
    33             get
    34             {
    35                 // Return the type of the editing control that CalendarCell uses.
    36                 return typeof(TreeViewEditingControl);
    37             }
    38         }
    39 
    40         public override Type ValueType
    41         {
    42             get
    43             {
    44                 // Return the type of the value that CalendarCell contains.
    45                 return typeof(String);
    46             }
    47         }
    48 
    49         public override object DefaultNewRowValue
    50         {
    51             get
    52             {
    53                 // Use the current date and time as the default value.
    54                 return "";
    55             }
    56         }
    57     }

    3 TreeViewEditingControl类

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

      1 public class TreeViewEditingControl : TreeView, IDataGridViewEditingControl
      2     {
      3         DataGridView dataGridView;
      4         private bool valueChanged = false;
      5         int rowIndex;
      6         public TreeViewEditingControl()
      7         {
      8             try
      9             {
     10                 //必须加Roots.tree.Nodes[0].Clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆
     11                 this.Nodes.Add(Roots.tree.Nodes[0].Clone() as TreeNode);
     12                 this.SelectedNode = this.Nodes[0];
     13 
     14               
     15             }
     16             catch (Exception ex)
     17             {
     18                 MessageBox.Show(ex.Message);
     19             }
     20            
     21          
     22         }
     23    
     24         // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
     25         // property.
     26         public object EditingControlFormattedValue
     27         {
     28             get
     29             {
     30                 return this.SelectedNode.Text;
     31             }
     32             set
     33             {
     34                 if (value is String)
     35                 {
     36                     try
     37                     {
     38                         // This will throw an exception of the string is 
     39                         // null, empty, or not in the format of a date.
     40                         this.SelectedNode = new TreeNode((String)value);
     41                         
     42                     }
     43                     catch
     44                     {
     45                         // In the case of an exception, just use the 
     46                         // default value so we're not left with a null
     47                         // value.
     48                         this.SelectedNode = new TreeNode("");
     49                     }
     50                 }
     51             }
     52         }
     53 
     54         // Implements the 
     55         // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
     56         public object GetEditingControlFormattedValue(
     57             DataGridViewDataErrorContexts context)
     58         {
     59             return EditingControlFormattedValue;
     60         }
     61 
     62         // Implements the 
     63         // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
     64         public void ApplyCellStyleToEditingControl(
     65             DataGridViewCellStyle dataGridViewCellStyle)
     66         {
     67             this.Font = dataGridViewCellStyle.Font;
     68             this.ForeColor = dataGridViewCellStyle.ForeColor;
     69             this.BackColor = dataGridViewCellStyle.BackColor;
     70         }
     71 
     72         // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
     73         // property.
     74         public int EditingControlRowIndex
     75         {
     76             get
     77             {
     78                 return rowIndex;
     79             }
     80             set
     81             {
     82                 rowIndex = value;
     83             }
     84         }
     85 
     86         // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
     87         // method.
     88         public bool EditingControlWantsInputKey(
     89             Keys key, bool dataGridViewWantsInputKey)
     90         {
     91             // Let the TreeViewPicker handle the keys listed.
     92             switch (key & Keys.KeyCode)
     93             {
     94                 case Keys.Left:
     95                 case Keys.Up:
     96                 case Keys.Down:
     97                 case Keys.Right:
     98                 case Keys.Home:
     99                 case Keys.End:
    100                 case Keys.PageDown:
    101                 case Keys.PageUp:
    102                     return true;
    103                 default:
    104                     return !dataGridViewWantsInputKey;
    105             }
    106         }
    107 
    108         // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    109         // method.
    110         public void PrepareEditingControlForEdit(bool selectAll)
    111         {
    112             // No preparation needs to be done.
    113         }
    114 
    115         // Implements the IDataGridViewEditingControl
    116         // .RepositionEditingControlOnValueChange property.
    117         public bool RepositionEditingControlOnValueChange
    118         {
    119             get
    120             {
    121                 return false;
    122             }
    123         }
    
    124 
    125         // Implements the IDataGridViewEditingControl
    126         // .EditingControlDataGridView property.
    127         public DataGridView EditingControlDataGridView
    128         {
    129             get
    130             {
    131                 return dataGridView;
    132             }
    133             set
    134             {
    135                 dataGridView = value;
    136             }
    137         }
    138 
    139         // Implements the IDataGridViewEditingControl
    140         // .EditingControlValueChanged property.
    141         public bool EditingControlValueChanged
    142         {
    143             get
    144             {
    145                 return valueChanged;
    146             }
    147             set
    148             {
    149                 valueChanged = value;
    150             }
    151         }
    152 
    153         // Implements the IDataGridViewEditingControl
    154         // .EditingPanelCursor property.
    155         public Cursor EditingPanelCursor
    156         {
    157             get
    158             {
    159                 return base.Cursor;
    160             }
    161         }
    162 
    163         protected override void OnAfterExpand(TreeViewEventArgs e)
    164         {
    165             base.OnAfterExpand(e);
    166             this.dataGridView.Columns[this.dataGridView.CurrentCell.ColumnIndex].Width = this.Width+10;
    167             this.dataGridView.Rows[this.dataGridView.CurrentCell.RowIndex].Height = this.Height+20;
    168            
    169         }
    170         protected override void OnAfterSelect(TreeViewEventArgs e)
    171         {
    172             // Notify the DataGridView that the contents of the cell
    173             // have changed.
    174             valueChanged = true;
    175             this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
    176             base.OnAfterSelect(e);
    177             
    178         }
    179        
    180     }

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

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

    完整代码为:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Windows.Forms;
      6 using System.ComponentModel;
      7 namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
      8 {
      9     /// <summary>
     10     /// 静态类的静态属性,用于在不同class间传递参数
     11     /// </summary>
     12     public static class Roots
     13     {
     14         //从前台绑定树
     15        public static TreeView tree = null;
     16     }
     17     /// <summary>
     18     /// Host TreeView In DataGridView Cell
     19     /// </summary>
     20    public class TreeViewColumn : DataGridViewColumn
     21     {
     22         public TreeViewColumn()
     23             : base(new TreeViewCell())
     24         {
     25         }
     26         [Description("Set TreeView Root in DataGridView Cell"), Category("TreeView")]
     27         public TreeView _root
     28         {
     29             get{return Roots.tree;}
     30             set{Roots.tree=value;}
     31         }
     32         public override DataGridViewCell CellTemplate
     33         {
     34             get
     35             {
     36                 return base.CellTemplate;
     37             }
     38             set
     39             {
    
     40                 // Ensure that the cell used for the template is a TreeViewCell.
     41                 if (value != null &&
     42                     !value.GetType().IsAssignableFrom(typeof(TreeViewCell)))
     43                 {
     44                     throw new InvalidCastException("Must be a TreeViewCell");
     45                 }
     46                 base.CellTemplate = value;
     47             }
     48         }
     49     }
     50 
     51     //----------------------------------------------------------------------
     52     public class TreeViewCell : DataGridViewTextBoxCell
     53     {
     54 
     55         public TreeViewCell()
     56             : base()
     57         {
     58         
     59             //初始设置
     60         }
     61        
     62         public override void InitializeEditingControl(int rowIndex, object
     63             initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
     64         {
     65             // Set the value of the editing control to the current cell value.
     66             base.InitializeEditingControl(rowIndex, initialFormattedValue,
     67                 dataGridViewCellStyle);
     68             TreeViewEditingControl ctl =
     69                 DataGridView.EditingControl as TreeViewEditingControl;
     70             // Use the default row value when Value property is null.
     71             if (this.Value == null)
     72             {
     73 
     74                 ctl.SelectedNode =new TreeNode( this.DefaultNewRowValue.ToString());
     75             }
     76             else
     77             {
     78                 ctl.SelectedNode = new TreeNode(this.Value.ToString());
     79             }
     80         }
     81 
     82         public override Type EditType
     83         {
     84             get
     85             {
     86                 // Return the type of the editing control that CalendarCell uses.
     87                 return typeof(TreeViewEditingControl);
     88             }
     89         }
     90 
     91         public override Type ValueType
     92         {
     93             get
     94             {
     95                 // Return the type of the value that CalendarCell contains.
     96                 return typeof(String);
     97             }
     98         }
     99 
    100         public override object DefaultNewRowValue
    101         {
    102             get
    103             {
    104                 // Use the current date and time as the default value.
    105                 return "";
    106             }
    107         }
    108     }
    109     //-----------------------------------------------------------------
    110 
    111    public class TreeViewEditingControl : TreeView, IDataGridViewEditingControl
    112     {
    113         DataGridView dataGridView;
    114         private bool valueChanged = false;
    115         int rowIndex;
    116         public TreeViewEditingControl()
    117         {
    118             try
    119             {
    120                 //必须加Roots.tree.Nodes[0].Clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆
    121                 this.Nodes.Add(Roots.tree.Nodes[0].Clone() as TreeNode);
    122                 this.SelectedNode = this.Nodes[0];
    123 
    124               
    125             }
    126             catch (Exception ex)
    127             {
    128                 MessageBox.Show(ex.Message);
    129             }
    130            
    131          
    132         }
    133    
    134         // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
    135         // property.
    136         public object EditingControlFormattedValue
    137         {
    138             get
    139             {
    140                 return this.SelectedNode.Text;
    141             }
    142             set
    143             {
    144                 if (value is String)
    145                 {
    146                     try
    147                     {
    148                         // This will throw an exception of the string is 
    149                         // null, empty, or not in the format of a date.
    150                         this.SelectedNode = new TreeNode((String)value);
    151                         
    152                     }
    153                     catch
    154                     {
    155                         // In the case of an exception, just use the 
    156                         // default value so we're not left with a null
    157                         // value.
    158                         this.SelectedNode = new TreeNode("");
    159                     }
    160                 }
    161             }
    162         }
    163 
    164         // Implements the 
    165         // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
    166         public object GetEditingControlFormattedValue(
    167             DataGridViewDataErrorContexts context)
    168         {
    169             return EditingControlFormattedValue;
    170         }
    171 
    172         // Implements the 
    173         // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
    174         public void ApplyCellStyleToEditingControl(
    175             DataGridViewCellStyle dataGridViewCellStyle)
    176         {
    177             this.Font = dataGridViewCellStyle.Font;
    178             this.ForeColor = dataGridViewCellStyle.ForeColor;
    179             this.BackColor = dataGridViewCellStyle.BackColor;
    180         }
    181 
    182         // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
    183         // property.
    184         public int EditingControlRowIndex
    185         {
    186             get
    187             {
    188                 return rowIndex;
    189             }
    190             set
    191             {
    192                 rowIndex = value;
    193             }
    194         }
    195 
    196         // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
    197         // method.
    198         public bool EditingControlWantsInputKey(
    199             Keys key, bool dataGridViewWantsInputKey)
    200         {
    201             // Let the TreeViewPicker handle the keys listed.
    202             switch (key & Keys.KeyCode)
    203             {
    204                 case Keys.Left:
    205                 case Keys.Up:
    206                 case Keys.Down:
    207                 case Keys.Right:
    208                 case Keys.Home:
    209                 case Keys.End:
    210                 case Keys.PageDown:
    211                 case Keys.PageUp:
    212                     return true;
    213                 default:
    214                     return !dataGridViewWantsInputKey;
    215             }
    216         }
    217 
    218         // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    219         // method.
    220         public void PrepareEditingControlForEdit(bool selectAll)
    221         {
    222             // No preparation needs to be done.
    223         }
    224 
    225         // Implements the IDataGridViewEditingControl
    226         // .RepositionEditingControlOnValueChange property.
    227         public bool RepositionEditingControlOnValueChange
    228         {
    229             get
    230             {
    231                 return false;
    232             }
    233         }
    234 
    235         // Implements the IDataGridViewEditingControl
    236         // .EditingControlDataGridView property.
    237         public DataGridView EditingControlDataGridView
    238         {
    239             get
    240             {
    241                 return dataGridView;
    242             }
    243             set
    244             {
    245                 dataGridView = value;
    246             }
    247         }
    248 
    249         // Implements the IDataGridViewEditingControl
    250         // .EditingControlValueChanged property.
    251         public bool EditingControlValueChanged
    252         {
    253             get
    254             {
    255                 return valueChanged;
    256             }
    257             set
    258             {
    259                 valueChanged = value;
    260             }
    261         }
    262 
    263         // Implements the IDataGridViewEditingControl
    264         // .EditingPanelCursor property.
    265         public Cursor EditingPanelCursor
    266         {
    267             get
    268             {
    269                 return base.Cursor;
    270             }
    271         }
    272 
    273         protected override void OnAfterExpand(TreeViewEventArgs e)
    274         {
    275             base.OnAfterExpand(e);
    276             this.dataGridView.Columns[this.dataGridView.CurrentCell.ColumnIndex].Width = this.Width+10;
    277             this.dataGridView.Rows[this.dataGridView.CurrentCell.RowIndex].Height = this.Height+20;
    278            
    279         }
    280         protected override void OnAfterSelect(TreeViewEventArgs e)
    281         {
    282             // Notify the DataGridView that the contents of the cell
    283             // have changed.
    284             valueChanged = true;
    285             this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
    286             base.OnAfterSelect(e);
    287             
    288         }
    289        
    290     }
    291 
    292 
    293 
    294 }
    View Code

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

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

     

  • 相关阅读:
    lms框架服务注册中心
    lms框架应用服务接口和服务条目详解
    lms框架模块详解
    lms微服务框架主机介绍
    lms框架分布式事务使用简介
    MySQL锁总结
    VSCode 输出 java SSL 请求过程
    PowerShell自动化发布SpringBoot项目到Tomcat
    AWS EC2 使用---安装Docker和Nginx
    使用PowerShell连接到Linux
  • 原文地址:https://www.cnblogs.com/isaboy/p/Host_TreeView_in_Windows_Forms_DataGridView_Cells.html
Copyright © 2020-2023  润新知