程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#如何自定義DataGridViewColumn來顯示TreeView,

C#如何自定義DataGridViewColumn來顯示TreeView,

編輯:C#入門知識

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。

  運行代碼,單擊單元格,進入編輯狀態,可以看到如下界面:

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved