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接口,实现以下方法:

C#如何自定义DataGridViewColumn来显示TreeView_第1张图片

 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

C#如何自定义DataGridViewColumn来显示TreeView_第2张图片

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

C#如何自定义DataGridViewColumn来显示TreeView_第3张图片

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

C#如何自定义DataGridViewColumn来显示TreeView_第4张图片

 

你可能感兴趣的:(C#如何自定义DataGridViewColumn来显示TreeView)