上一篇博文探討了如何自定義DataGridViewColumn實現一個TreeViewColumn來在DataGridView控件中顯示TreeView控件,其實我們還可以繼續發揮想象,自定義其他的列類型,下面介紹一個腳本編輯器列類型,我這裡取名ScriptTextEditorColumn,當用戶單擊DataGridView的ScriptTextEditorColumn時,單元格右邊會出現一個按鈕,單擊按鈕會彈出一個腳本編輯器窗體,用戶可以在窗體中進行代碼維護,然後回寫到單元格中。
用人會問,這個控件有啥實際作用,其實結合動態編譯的技術,在datagridview中進行取值公式的模板設定,也就是在對應的單元格中設置C#腳本,然後動態執行後呈現結果到一個datagridview單元格中,這樣就實現了動態配置datagridview後台計算邏輯的目的,當然實現這樣的功能還需要大量的工作,但是主要的思路就是這樣。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows.Forms;
6
7 namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
8 {
9 public class ScriptTextEditorColumn : DataGridViewColumn
10 {
11 public ScriptTextEditorColumn()
12 : base(new ScriptTextEditorCell())
13 {
14 }
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 ScriptTextEditorCell.
25 if (value != null &&
26 !value.GetType().IsAssignableFrom(typeof(ScriptTextEditorCell)))
27 {
28 throw new InvalidCastException("Must be a ScriptTextEditorCell");
29 }
30 base.CellTemplate = value;
31 }
32 }
33 }
34
35 //----------------------------------------------------------------------
36 public class ScriptTextEditorCell : DataGridViewTextBoxCell
37 {
38
39 public ScriptTextEditorCell()
40 : base()
41 {
42
43 }
44
45 public override void InitializeEditingControl(int rowIndex, object
46 initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
47 {
48 // Set the value of the editing control to the current cell value.
49 base.InitializeEditingControl(rowIndex, initialFormattedValue,
50 dataGridViewCellStyle);
51 ScriptTextEditingControl ctl =
52 DataGridView.EditingControl as ScriptTextEditingControl;
53 // Use the default row value when Value property is null.
54 if (this.Value == null)
55 {
56 ctl.textBox1.Text = (String)this.DefaultNewRowValue;
57 }
58 else
59 {
60 ctl.textBox1.Text = (String)this.Value;
61 }
62 }
63
64 public override Type EditType
65 {
66 get
67 {
68 // Return the type of the editing control that CalendarCell uses.
69 return typeof(ScriptTextEditingControl);
70 }
71 }
72
73 public override Type ValueType
74 {
75 get
76 {
77 // Return the type of the value that CalendarCell contains.
78
79 return typeof(String);
80 }
81 }
82
83 public override object DefaultNewRowValue
84 {
85 get
86 {
87 // Use the current date and time as the default value.
88 string code = @"
89 #region
90 //jackwangcumt
91 #endregion
92 using System;
93 using System.Collections.Generic;
94 using System.ComponentModel;
95 using System.Drawing;
96 using System.Data;
97 using System.Linq;
98 using System.Text;
99 using System.Windows.Forms;
100 namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
101 {
102 public partial class SourceTextBox : UserControl
103 {
104 public SourceTextBox()
105 {
106 InitializeComponent();
107 this.textBox1.Location = this.Location;
108 this.textBox1.Width = this.Width;
109 this.textBox1.Height = this.Height;
110 }
111 protected void OnValueChanged(string text)
112 {
113 this.textBox1.Text = text;
114 }
115
116 private void btnSource_Click(object sender, EventArgs e)
117 {
118 ScriptEditor frm = new ScriptEditor(this.textBox1.Text);
119 frm.ShowDialog();
120 this.textBox1.Text = frm.fastColoredTextBox1.Text;
121 }
122 }
123 }
124 ";
125 return code;
126 }
127 }
128 }
129 //-----------------------------------------------------------------
130
131 class ScriptTextEditingControl : SourceTextBox, IDataGridViewEditingControl
132 {
133 DataGridView dataGridView;
134 private bool valueChanged = false;
135 int rowIndex;
136
137 public ScriptTextEditingControl()
138 {
139 //文本變更更新到cell
140 this.textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
141 }
142
143 void textBox1_TextChanged(object sender, EventArgs e)
144 {
145 // Notify the DataGridView that the contents of the cell
146 // have changed.
147 valueChanged = true;
148 this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
149 //調用SourceTextBox的OnValueChanged(string Text)
150 base.OnValueChanged(this.textBox1.Text);
151 }
152
153 // Implements the IDataGridViewEditingControl.EditingControlFormattedValue
154 // property.
155 public object EditingControlFormattedValue
156 {
157 get
158 {
159 return this.textBox1.Text;
160 }
161 set
162 {
163 if (value is String)
164 {
165 try
166 {
167 // This will throw an exception of the string is
168 // null, empty, or not in the format of a date.
169 this.textBox1.Text=((String)value);
170 }
171 catch
172 {
173 // In the case of an exception, just use the
174 // default value so we're not left with a null
175 // value.
176 this.textBox1.Text = "jackwangcumt>>error";
177 }
178 }
179 }
180 }
181
182 // Implements the
183 // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
184 public object GetEditingControlFormattedValue(
185 DataGridViewDataErrorContexts context)
186 {
187 return EditingControlFormattedValue;
188 }
189
190 // Implements the
191 // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
192 public void ApplyCellStyleToEditingControl(
193 DataGridViewCellStyle dataGridViewCellStyle)
194 {
195 this.Font = dataGridViewCellStyle.Font;
196 //this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
197 //this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
198 }
199
200 // Implements the IDataGridViewEditingControl.EditingControlRowIndex
201 // property.
202 public int EditingControlRowIndex
203 {
204 get
205 {
206 return rowIndex;
207 }
208 set
209 {
210 rowIndex = value;
211 }
212 }
213
214 // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey
215 // method.
216 public bool EditingControlWantsInputKey(
217 Keys key, bool dataGridViewWantsInputKey)
218 {
219 // Let the DateTimePicker handle the keys listed.
220 switch (key & Keys.KeyCode)
221 {
222 case Keys.Left:
223 case Keys.Up:
224 case Keys.Down:
225 case Keys.Right:
226 case Keys.Home:
227 case Keys.End:
228 case Keys.PageDown:
229 case Keys.PageUp:
230 return true;
231 default:
232 return !dataGridViewWantsInputKey;
233 }
234 }
235
236 // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit
237 // method.
238 public void PrepareEditingControlForEdit(bool selectAll)
239 {
240 // No preparation needs to be done.
241 }
242
243 // Implements the IDataGridViewEditingControl
244 // .RepositionEditingControlOnValueChange property.
245 public bool RepositionEditingControlOnValueChange
246 {
247 get
248 {
249 return false;
250 }
251 }
252
253 // Implements the IDataGridViewEditingControl
254 // .EditingControlDataGridView property.
255 public DataGridView EditingControlDataGridView
256 {
257 get
258 {
259 return dataGridView;
260 }
261 set
262 {
263 dataGridView = value;
264 }
265 }
266
267 // Implements the IDataGridViewEditingControl
268 // .EditingControlValueChanged property.
269 public bool EditingControlValueChanged
270 {
271 get
272 {
273 return valueChanged;
274 }
275 set
276 {
277 valueChanged = value;
278 }
279 }
280
281 // Implements the IDataGridViewEditingControl
282 // .EditingPanelCursor property.
283 public Cursor EditingPanelCursor
284 {
285 get
286 {
287 return base.Cursor;
288 }
289 }
290
291 protected override void OnTextChanged(EventArgs e)
292 {
293 // Notify the DataGridView that the contents of the cell
294 // have changed.
295 valueChanged = true;
296 this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
297 base.OnTextChanged(e);
298
299 }
300
301 }
302
303
304
305 }
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9
10 namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
11 {
12 public partial class SourceTextBox : UserControl
13 {
14 public SourceTextBox()
15 {
16 InitializeComponent();
17 this.textBox1.Location = this.Location;
18 this.textBox1.Width = this.Width;
19 this.textBox1.Height = this.Height;
20 }
21 protected void OnValueChanged(string text)
22 {
23 this.textBox1.Text = text;
24 }
25
26 private void btnSource_Click(object sender, EventArgs e)
27 {
28 ScriptEditor frm = new ScriptEditor(this.textBox1.Text);
29 frm.ShowDialog();
30 this.textBox1.Text = frm.fastColoredTextBox1.Text;
31 }
32 }
33 }

