代码如下
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 using System.Collections;
10 using System.Reflection;
11 using Newtonsoft.Json.Linq;
12
13 namespace ControlsAA
14 {
15 public class ComboBoxEx : ComboBox
16 {
17 TreeView lst = new TreeView();
18
19 public ComboBoxEx()
20 {
21 this.DrawMode = DrawMode.OwnerDrawFixed;//只有设置这个属性为OwnerDrawFixed才可能让重画起作用
22 lst.KeyUp += new KeyEventHandler(lst_KeyUp);
23 lst.MouseUp += new MouseEventHandler(lst_MouseUp);
24 // lst.KeyDown += new KeyEventHandler(lst_KeyDown);
25 lst.Leave += new EventHandler(lst_Leave);
26 lst.CheckBoxes = true;
27 lst.ShowLines = false;
28 lst.ShowPlusMinus = false;
29 lst.ShowRootLines = false;
30 this.DropDownHeight = 1;
31 }
32
33 void lst_Leave(object sender, EventArgs e)
34 {
35 lst.Hide();
36 }
37 #region Property
38
39 [Description("选定项的值"), Category("Data")]
40 public List<TreeNode> SelectedItems
41 {
42 get
43 {
44 List<TreeNode> lsttn = new List<TreeNode>();
45 foreach (TreeNode tn in lst.Nodes)
46 {
47 if (tn.Checked)
48 {
49 lsttn.Add(tn);
50 }
51 }
52 return lsttn;
53 }
54 }
55
56 /// <summary>
57 /// 数据源
58 /// </summary>
59 [Description("数据源"), Category("Data")]
60 public object DataSource
61 {
62 get;
63 set;
64 }
65 /// <summary>
66 /// 显示字段
67 /// </summary>
68 [Description("显示字段"), Category("Data")]
69 public string DisplayFiled
70 {
71 get;
72 set;
73 }
74 /// <summary>
75 /// 值字段
76 /// </summary>
77 [Description("值字段"), Category("Data")]
78 public string ValueFiled
79 {
80 get;
81 set;
82 }
83 #endregion
84
85
86 public void DataBind()
87 {
88 this.BeginUpdate();
89 if (DataSource != null)
90 {
91 if (DataSource is IDataReader)
92 {
93 DataTable dataTable = new DataTable();
94 dataTable.Load(DataSource as IDataReader);
95
96 DataBindToDataTable(dataTable);
97 }
98 else if (DataSource is DataView || DataSource is DataSet || DataSource is DataTable)
99 {
100 DataTable dataTable = null;
101
102 if (DataSource is DataView)
103 {
104 dataTable = ((DataView)DataSource).ToTable();
105 }
106 else if (DataSource is DataSet)
107 {
108 dataTable = ((DataSet)DataSource).Tables[0];
109 }
110 else
111 {
112 dataTable = ((DataTable)DataSource);
113 }
114
115 DataBindToDataTable(dataTable);
116 }
117 else if (DataSource is IEnumerable)
118 {
119 DataBindToEnumerable((IEnumerable)DataSource);
120 }
121 else
122 {
123 throw new Exception("DataSource doesn't support data type: " + DataSource.GetType().ToString());
124 }
125 }
126 else
127 {
128 lst.Nodes.Clear();
129 }
130
131 lst.ItemHeight = this.ItemHeight;
132 lst.BorderStyle = BorderStyle.FixedSingle;
133 lst.Size = new Size(this.DropDownWidth, this.ItemHeight * (this.MaxDropDownItems - 1) - (int)this.ItemHeight / 2);
134 lst.Location = new Point(this.Left, this.Top + this.ItemHeight + 6);
135 this.Parent.Controls.Add(lst);
136 lst.Hide();
137 this.EndUpdate();
138 }
139
140
141 private void DataBindToDataTable(DataTable dt)
142 {
143 foreach (DataRow dr in dt.Rows)
144 {
145 TreeNode tn = new TreeNode();
146 if (!string.IsNullOrEmpty(DisplayFiled) && !string.IsNullOrEmpty(ValueFiled))
147 {
148 tn.Text = dr[DisplayFiled].ToString();
149 tn.Tag = dr[ValueFiled].ToString();
150 }
151 else if (string.IsNullOrEmpty(ValueFiled))
152 {
153 tn.Text = dr[DisplayFiled].ToString();
154 tn.Tag = dr[DisplayFiled].ToString();
155 }
156 else if (string.IsNullOrEmpty(DisplayFiled))
157 {
158 tn.Text = dr[ValueFiled].ToString();
159 tn.Tag = dr[ValueFiled].ToString();
160 }
161 else
162 {
163 throw new Exception("ValueFiled和DisplayFiled至少保证有一项有值");
164 }
165
166 tn.Checked = false;
167 lst.Nodes.Add(tn);
168 }
169 }
170
171 /// <summary>
172 /// 绑定到可枚举类型
173 /// </summary>
174 /// <param name="enumerable">可枚举类型</param>
175 private void DataBindToEnumerable(IEnumerable enumerable)
176 {
177 IEnumerator enumerator = enumerable.GetEnumerator();
178 while (enumerator.MoveNext())
179 {
180 object currentObject = enumerator.Current;
181 lst.Nodes.Add(CreateListItem(currentObject));
182 }
183 }
184
185
186
187 private TreeNode CreateListItem(Object obj)
188 {
189 TreeNode item = new TreeNode();
190
191 if (obj is string)
192 {
193 item.Text = obj.ToString();
194 item.Tag = obj.ToString();
195 }
196 else
197 {
198 if (DisplayFiled != "")
199 {
200 item.Text = GetPropertyValue(obj, DisplayFiled);
201 }
202 else
203 {
204 item.Text = obj.ToString();
205 }
206
207 if (ValueFiled != "")
208 {
209 item.Tag = GetPropertyValue(obj, ValueFiled);
210 }
211 else
212 {
213 item.Tag = obj.ToString();
214 }
215 }
216 return item;
217 }
218
219
220 private string GetPropertyValue(object obj, string propertyName)
221 {
222 object result = null;
223
224 result = ObjectUtil.GetPropertyValue(obj, propertyName);
225 return result == null ? String.Empty : result.ToString();
226 }
227
228 #region override
229
230
231 protected override void OnKeyUp(KeyEventArgs e)
232 {
233 base.OnKeyDown(e);
234 bool Pressed = (e.Control && ((e.KeyData & Keys.A) == Keys.A));
235 if (Pressed)
236 {
237 this.Text = "";
238 for (int i = 0; i < lst.Nodes.Count; i++)
239 {
240 lst.Nodes[i].Checked = true;
241 if (this.Text != "")
242 {
243 this.Text += ",";
244 }
245 this.Text += lst.Nodes[i].Tag;
246 }
247 }
248 }
249
250 protected override void OnMouseDown(MouseEventArgs e)
251 {
252 this.DroppedDown = false;
253
254 }
255
256 protected override void OnMouseUp(MouseEventArgs e)
257 {
258 this.DroppedDown = false;
259 lst.Focus();
260 }
261
262 protected override void OnDropDown(EventArgs e)
263 {
264 string strValue = this.Text;
265 if (!string.IsNullOrEmpty(strValue))
266 {
267 List<string> lstvalues = strValue.Split(',').ToList<string>();
268 foreach (TreeNode tn in lst.Nodes)
269 {
270 if (tn.Checked && !lstvalues.Contains(tn.Tag.ToString()) && !string.IsNullOrEmpty(tn.Tag.ToString().Trim()))
271 {
272 tn.Checked = false;
273 }
274 else if (!tn.Checked && lstvalues.Contains(tn.Tag.ToString()) && !string.IsNullOrEmpty(tn.Tag.ToString().Trim()))
275 {
276 tn.Checked = true;
277 }
278 }
279 }
280
281 lst.Show();
282
283 }
284 #endregion
285
286 private void lst_KeyUp(object sender, KeyEventArgs e)
287 {
288 this.OnKeyUp(e);
289 }
290
291 private void lst_MouseUp(object sender, MouseEventArgs e)
292 {
293 try
294 {
295 this.Text = "";
296 for (int i = 0; i < lst.Nodes.Count; i++)
297 {
298 if (lst.Nodes[i].Checked)
299 {
300 if (this.Text != "")
301 {
302 this.Text += ",";
303 }
304 this.Text += lst.Nodes[i].Tag;
305 }
306 }
307 }
308 catch
309 {
310 this.Text = "";
311 }
312 bool isControlPressed = (Control.ModifierKeys == Keys.Control);
313 bool isShiftPressed = (Control.ModifierKeys == Keys.Shift);
314 if (isControlPressed || isShiftPressed)
315 lst.Show();
316 else
317 lst.Hide();
318 }
319
320 }
321
322
323 /// <summary>
324 /// 对象帮助类
325 /// </summary>
326 public class ObjectUtil
327 {
328 /// <summary>
329 /// 获取对象的属性值
330 /// </summary>
331 /// <param name="obj">可能是DataRowView或一个对象</param>
332 /// <param name="propertyName">属性名</param>
333 /// <returns>属性值</returns>
334 public static object GetPropertyValue(object obj, string propertyName)
335 {
336 object result = null;
337
338 try
339 {
340 if (obj is DataRow)
341 {
342 result = (obj as DataRow)[propertyName];
343 }
344 else if (obj is DataRowView)
345 {
346 result = (obj as DataRowView)[propertyName];
347 }
348 else if (obj is JObject)
349 {
350 result = (obj as JObject).Value<JValue>(propertyName).Value; //.getValue(propertyName);
351 }
352 else
353 {
354 result = GetPropertyValueFormObject(obj, propertyName);
355 }
356 }
357 catch (Exception)
358 {
359 // 找不到此属性
360 }
361
362 return result;
363 }
364
365 /// <summary>
366 /// 获取对象的属性值
367 /// </summary>
368 /// <param name="obj">对象</param>
369 /// <param name="propertyName">属性名("Color"、"BodyStyle"或者"Info.UserName")</param>
370 /// <returns>属性值</returns>
371 private static object GetPropertyValueFormObject(object obj, string propertyName)
372 {
373 object rowObj = obj;
374 object result = null;
375
376 if (propertyName.IndexOf(".") > 0)
377 {
378 string[] properties = propertyName.Split('.');
379 object tmpObj = rowObj;
380
381 for (int i = 0; i < properties.Length; i++)
382 {
383 PropertyInfo property = tmpObj.GetType().GetProperty(properties[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
384 if (property != null)
385 {
386 tmpObj = property.GetValue(tmpObj, null);
387 }
388 }
389
390 result = tmpObj;
391 }
392 else
393 {
394 PropertyInfo property = rowObj.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
395 if (property != null)
396 {
397 result = property.GetValue(rowObj, null);
398 }
399 }
400
401 return result;
402 }
403 }
404 }