我们可以自定义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 }
完整代码为:
当编辑无误后,可以在添加列的时候看到TreeViewColumn类型。此类型暴露出一个_root属性,可以绑定外部的一个带数据的TreeView。
运行代码,单击单元格,进入编辑状态,可以看到如下界面:
出处: http://www.cnblogs.com/isaboy/
声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。