CklCheckedListBox.cs 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Security.Permissions;
  8. using System.Windows.Forms;
  9. using Dongke.WinForm.Utilities;
  10. namespace Dongke.WinForm.Controls
  11. {
  12. /// <summary>
  13. /// 标准复选框列表控件
  14. /// </summary>
  15. [ToolboxBitmap(typeof(CheckedListBox))]
  16. [DefaultBindingProperty("SelectedValue"), DefaultProperty("Items"), DefaultEvent("ItemChecked")]
  17. [LookupBindingProperties("DataSource", "DisplayMember", "ValueMember", "SelectedValue")]
  18. public class CklCheckedListBox : CheckedListBox, IDKControl, IDataVerifiable, IAsyncControl
  19. {
  20. #region 事件声明
  21. #region ItemChecked
  22. /// <summary>
  23. /// 当某项的选中状态更改后发生
  24. /// </summary>
  25. private static readonly object EventItemChecked = new object();
  26. /// <summary>
  27. /// 当某项的选中状态更改后发生。
  28. /// </summary>
  29. [Description("当某项的选中状态更改后发生。"), Category("CustomerEx")]
  30. public event ItemCheckedEventHandler ItemChecked
  31. {
  32. add
  33. {
  34. base.Events.AddHandler(EventItemChecked, value);
  35. }
  36. remove
  37. {
  38. base.Events.RemoveHandler(EventItemChecked, value);
  39. }
  40. }
  41. #endregion
  42. #region HasErrorChanged
  43. /// <summary>
  44. /// 当 HasError 属性的值更改时发生。
  45. /// </summary>
  46. private static readonly object EventHasErrorChanged = new object();
  47. /// <summary>
  48. /// 当 HasError 属性的值更改时发生。
  49. /// </summary>
  50. [Description("当 HasError 属性的值更改时发生。"), Category("CustomerEx")]
  51. public event EventHandler HasErrorChanged
  52. {
  53. add
  54. {
  55. base.Events.AddHandler(EventHasErrorChanged, value);
  56. }
  57. remove
  58. {
  59. base.Events.RemoveHandler(EventHasErrorChanged, value);
  60. }
  61. }
  62. #endregion
  63. #endregion
  64. #region 成员变量
  65. /// <summary>
  66. /// 焦点是否进入控件
  67. /// </summary>
  68. private bool _entered = false;
  69. /// <summary>
  70. /// 鼠标是否进入控件
  71. /// </summary>
  72. private bool _mouseOver = false;
  73. /// <summary>
  74. /// 边框颜色
  75. /// </summary>
  76. private Color? _borderColor = null;
  77. /// <summary>
  78. /// 是否单选
  79. /// </summary>
  80. private bool _simpleChecked = false;
  81. /// <summary>
  82. /// 正在处理必须选中
  83. /// </summary>
  84. private bool _isMustChecking = false;
  85. /// <summary>
  86. /// 正在处理单项选中
  87. /// </summary>
  88. private bool _isSimpleChecking = false;
  89. /// <summary>
  90. /// 上次选中项个数
  91. /// </summary>
  92. private int _inputCount = -1;
  93. #endregion
  94. #region 构造函数
  95. /// <summary>
  96. /// 标准复选框列表控件
  97. /// </summary>
  98. public CklCheckedListBox()
  99. {
  100. base.CheckOnClick = true;
  101. base.FormattingEnabled = false;
  102. base.ThreeDCheckBoxes = false;
  103. CommonSetting.InitControls(this);
  104. }
  105. #endregion
  106. #region 属性
  107. /// <summary>
  108. /// 获取选中的文本
  109. /// </summary>
  110. [Description("获取选中的文本。"), Category("CustomerEx")]
  111. [DefaultValue(null)]
  112. public string[] CheckedTexts
  113. {
  114. get
  115. {
  116. List<string> checkedTexts = this.GetCheckedItemTexts();
  117. return checkedTexts.ToArray();
  118. }
  119. }
  120. /// <summary>
  121. /// 获取选中的值
  122. /// </summary>
  123. [Description("获取选中的值。"), Category("CustomerEx")]
  124. [DefaultValue(null)]
  125. public object[] CheckedValues
  126. {
  127. get
  128. {
  129. List<object> checkedValues = this.GetCheckedItemValues();
  130. return checkedValues.ToArray();
  131. }
  132. }
  133. /// <summary>
  134. /// 获取选中项的文本表示形式,用【,】隔开。
  135. /// </summary>
  136. [Description("获取选中项的文本表示形式,用【,】隔开。"), Category("CustomerEx")]
  137. [DefaultValue(null)]
  138. public string CheckedText
  139. {
  140. get
  141. {
  142. string text =
  143. string.Join(Constant.MULTIPLE_TEXT_SEPARATOR,
  144. this.GetCheckedItemTexts());
  145. return text;
  146. }
  147. }
  148. /// <summary>
  149. /// 获取选中项的值,用【,】隔开
  150. /// </summary>
  151. [Description("获取选中项的值,用【,】隔开。"), Category("CustomerEx")]
  152. [DefaultValue(null)]
  153. public string CheckedValue
  154. {
  155. get
  156. {
  157. string value =
  158. string.Join(Constant.MULTIPLE_VALUE_SEPARATOR,
  159. this.GetCheckedItemValues());
  160. return value;
  161. }
  162. }
  163. /// <summary>
  164. /// 获取或设置控件是否单项选中。
  165. /// </summary>
  166. [Description("获取或设置控件是否单项选中。"), Category("CustomerEx")]
  167. [DefaultValue(false)]
  168. public bool SimpleChecked
  169. {
  170. get
  171. {
  172. return this._simpleChecked;
  173. }
  174. set
  175. {
  176. if (this._simpleChecked != value)
  177. {
  178. this._simpleChecked = value;
  179. this.ResetMustOrSimpleChecked();
  180. }
  181. }
  182. }
  183. /// <summary>
  184. /// 获取一个值,该值指示控件是否有输入焦点。
  185. /// </summary>
  186. [DefaultValue(false)]
  187. [Browsable(false)]
  188. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  189. [EditorBrowsable(EditorBrowsableState.Advanced)]
  190. public virtual bool Entered
  191. {
  192. get
  193. {
  194. return this._entered;
  195. }
  196. protected set
  197. {
  198. if (this._entered != value)
  199. {
  200. this._entered = value;
  201. this.InvalidateBorder();
  202. }
  203. }
  204. }
  205. /// <summary>
  206. /// 获取一个值,该值指示鼠标是否在控件上方。
  207. /// </summary>
  208. [DefaultValue(false)]
  209. [Browsable(false)]
  210. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  211. [EditorBrowsable(EditorBrowsableState.Advanced)]
  212. public virtual bool MouseOver
  213. {
  214. get
  215. {
  216. return this._mouseOver;
  217. }
  218. protected set
  219. {
  220. if (this._mouseOver != value)
  221. {
  222. this._mouseOver = value;
  223. this.InvalidateBorder();
  224. }
  225. }
  226. }
  227. #endregion
  228. #region 重写属性
  229. /// <summary>
  230. /// 获取或设置一个值,该值指示当选定项时是否应切换复选框
  231. /// </summary>
  232. [DefaultValue(true)]
  233. //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  234. //[EditorBrowsable(EditorBrowsableState.Never)]
  235. public new bool CheckOnClick
  236. {
  237. get
  238. {
  239. return base.CheckOnClick;
  240. }
  241. set
  242. {
  243. base.CheckOnClick = value;
  244. }
  245. }
  246. /// <summary>
  247. /// 获取或设置控件的数据源
  248. /// </summary>
  249. [Description("获取或设置控件的数据源。"), Category("CustomerEx")]
  250. [DefaultValue(null)]
  251. [Browsable(true)]
  252. public new object DataSource
  253. {
  254. get
  255. {
  256. return base.DataSource;
  257. }
  258. set
  259. {
  260. string displayMember = base.DisplayMember;
  261. base.DataSource = value;
  262. base.DisplayMember = displayMember;
  263. //if (!this._mustInput)
  264. {
  265. this.SelectedIndex = -1;
  266. }
  267. }
  268. }
  269. /// <summary>
  270. /// 获取或设置一个字符串,该字符串指定要显示其内容的列表框中所含对象的属性
  271. /// </summary>
  272. [Description("获取或设置一个字符串,该字符串指定要显示其内容的列表框中所含对象的属性。"), Category("CustomerEx")]
  273. [DefaultValue("")]
  274. [Browsable(true)]
  275. public new string DisplayMember
  276. {
  277. get
  278. {
  279. return base.DisplayMember;
  280. }
  281. set
  282. {
  283. base.DisplayMember = value;
  284. }
  285. }
  286. /// <summary>
  287. /// 获取或设置一个字符串,该字符串指定要从中取值的数据源的属性
  288. /// </summary>
  289. [Description("获取或设置一个字符串,该字符串指定要从中取值的数据源的属性。"), Category("CustomerEx")]
  290. [DefaultValue("")]
  291. [Browsable(true)]
  292. public new string ValueMember
  293. {
  294. get
  295. {
  296. return base.ValueMember;
  297. }
  298. set
  299. {
  300. base.ValueMember = value;
  301. }
  302. }
  303. #endregion
  304. #region 重写事件
  305. #region 属性改变
  306. /// <summary>
  307. /// 引发 DataSourceChanged 事件。
  308. /// </summary>
  309. /// <param name="e"></param>
  310. protected override void OnDataSourceChanged(EventArgs e)
  311. {
  312. try
  313. {
  314. base.OnDataSourceChanged(e);
  315. }
  316. catch
  317. {
  318. }
  319. this.ResetMustOrSimpleChecked();
  320. }
  321. /// <summary>
  322. ///
  323. /// </summary>
  324. /// <param name="e"></param>
  325. protected override void OnDisplayMemberChanged(EventArgs e)
  326. {
  327. base.OnDisplayMemberChanged(e);
  328. this.ResetMustOrSimpleChecked();
  329. }
  330. /// <summary>
  331. ///
  332. /// </summary>
  333. /// <param name="e"></param>
  334. protected override void OnValueMemberChanged(EventArgs e)
  335. {
  336. base.OnValueMemberChanged(e);
  337. this.ResetMustOrSimpleChecked();
  338. }
  339. /// <summary>
  340. /// 引发 HasErrorChanged 事件
  341. /// </summary>
  342. /// <param name="e">包含事件数据的 EventArgs</param>
  343. protected virtual void OnHasErrorChanged(EventArgs e)
  344. {
  345. EventHandler eventHandler = (EventHandler)base.Events[EventHasErrorChanged];
  346. if (eventHandler != null)
  347. {
  348. eventHandler(this, e);
  349. }
  350. }
  351. #endregion
  352. #region 行为事件
  353. /// <summary>
  354. /// 引发 ItemCheck 事件
  355. /// </summary>
  356. /// <param name="ice"></param>
  357. protected override void OnItemCheck(ItemCheckEventArgs ice)
  358. {
  359. if (this._isMustChecking)
  360. {
  361. return;
  362. }
  363. if (this._isSimpleChecking)
  364. {
  365. base.OnItemCheck(ice);
  366. if (ice.NewValue == CheckState.Indeterminate)
  367. {
  368. ice.NewValue = CheckState.Checked;
  369. }
  370. return;
  371. }
  372. int checkedCount = (ice.NewValue == CheckState.Unchecked ? -1 : 1) + this.CheckedIndices.Count;
  373. if (this._mustInput && checkedCount == 0)
  374. {
  375. this._isMustChecking = true;
  376. //base.SetItemChecked(ice.Index, true);
  377. ice.NewValue = CheckState.Checked;
  378. this._isMustChecking = false;
  379. return;
  380. }
  381. if (this._simpleChecked && checkedCount > 1)
  382. {
  383. this._isSimpleChecking = true;
  384. foreach (int index in this.CheckedIndices)
  385. {
  386. if (index != ice.Index)
  387. {
  388. base.SetItemChecked(index, false);
  389. //this.SetItemChecked(index, false);
  390. }
  391. }
  392. this._isSimpleChecking = false;
  393. }
  394. base.OnItemCheck(ice);
  395. if (ice.NewValue == CheckState.Indeterminate)
  396. {
  397. ice.NewValue = CheckState.Checked;
  398. }
  399. }
  400. /// <summary>
  401. /// 引发 ItemChecked 事件
  402. /// </summary>
  403. /// <param name="ice">包含事件数据的 ItemCheckedEventArgs</param>
  404. protected virtual void OnItemChecked(ItemCheckedEventArgs ice)
  405. {
  406. ItemCheckedEventHandler eventHandler = (ItemCheckedEventHandler)base.Events[EventItemChecked];
  407. if (eventHandler != null)
  408. {
  409. eventHandler(this, ice);
  410. }
  411. }
  412. #endregion
  413. #region 键盘事件
  414. /// <summary>
  415. /// 引发 System.Windows.Forms.Control.KeyPress 事件
  416. /// </summary>
  417. /// <param name="e">所引发的 System.Windows.Forms.KeyPressEventArgs</param>
  418. protected override void OnKeyPress(KeyPressEventArgs e)
  419. {
  420. if (e.KeyChar == Constant.C_SPACE && this.SelectionMode != SelectionMode.None)
  421. {
  422. int selectedIndex = this.SelectedIndex;
  423. if (selectedIndex < 0 || selectedIndex >= this.Items.Count)
  424. {
  425. base.OnKeyPress(e);
  426. return;
  427. }
  428. CheckState checkedState = this.GetItemCheckState(selectedIndex);
  429. base.OnKeyPress(e);
  430. CheckState newCheckValue = this.GetItemCheckState(selectedIndex);
  431. if (checkedState != newCheckValue)
  432. {
  433. this.CheckOnItemChecked();
  434. ItemCheckedEventArgs itemCheckedEventArgs =
  435. new ItemCheckedEventArgs(selectedIndex, newCheckValue, checkedState);
  436. this.OnItemChecked(itemCheckedEventArgs);
  437. }
  438. }
  439. else
  440. {
  441. base.OnKeyPress(e);
  442. }
  443. }
  444. /// <summary>
  445. /// 键盘点击
  446. /// </summary>
  447. /// <param name="e"></param>
  448. protected override void OnKeyDown(KeyEventArgs e)
  449. {
  450. base.OnKeyDown(e);
  451. if (this.SelectedIndex < 1 && (e.KeyCode == Keys.Up || e.KeyCode == Keys.Left))
  452. {
  453. this.SelectPrevItem();
  454. e.Handled = true;
  455. return;
  456. }
  457. if (this.SelectedIndex == this.Items.Count - 1 &&
  458. (e.KeyCode == Keys.Down || e.KeyCode == Keys.Right))
  459. {
  460. this.SelectNextItem();
  461. e.Handled = true;
  462. return;
  463. }
  464. }
  465. #endregion
  466. #region 焦点事件
  467. /// <summary>
  468. /// 输入焦点进入控件
  469. /// </summary>
  470. /// <param name="e"></param>
  471. protected override void OnEnter(EventArgs e)
  472. {
  473. this.Entered = true;
  474. base.OnEnter(e);
  475. }
  476. /// <summary>
  477. /// 获得焦点
  478. /// </summary>
  479. /// <param name="e"></param>
  480. protected override void OnGotFocus(EventArgs e)
  481. {
  482. base.OnGotFocus(e);
  483. }
  484. /// <summary>
  485. /// 失去焦点
  486. /// </summary>
  487. /// <param name="e"></param>
  488. protected override void OnLostFocus(EventArgs e)
  489. {
  490. base.OnLostFocus(e);
  491. }
  492. /// <summary>
  493. /// 输入焦点离开控件
  494. /// </summary>
  495. /// <param name="e"></param>
  496. protected override void OnLeave(EventArgs e)
  497. {
  498. base.OnLeave(e);
  499. //this.Entered = false;
  500. }
  501. /// <summary>
  502. /// 控件正在验证
  503. /// </summary>
  504. /// <param name="e"></param>
  505. protected override void OnValidating(CancelEventArgs e)
  506. {
  507. base.OnValidating(e);
  508. if (this.HasError && !this._canLostFocusOnError)
  509. {
  510. e.Cancel = true;
  511. }
  512. }
  513. /// <summary>
  514. /// 控件完成验证
  515. /// </summary>
  516. /// <param name="e"></param>
  517. protected override void OnValidated(EventArgs e)
  518. {
  519. this.Entered = false;
  520. base.OnValidated(e);
  521. }
  522. #endregion
  523. #region 鼠标事件
  524. /// <summary>
  525. /// 鼠标进入控件
  526. /// </summary>
  527. /// <param name="e"></param>
  528. protected override void OnMouseEnter(EventArgs e)
  529. {
  530. this.MouseOver = true;
  531. base.OnMouseEnter(e);
  532. }
  533. /// <summary>
  534. /// 鼠标离开控件
  535. /// </summary>
  536. /// <param name="e"></param>
  537. protected override void OnMouseLeave(EventArgs e)
  538. {
  539. base.OnMouseLeave(e);
  540. this.MouseOver = false;
  541. }
  542. /// <summary>
  543. /// 鼠标移动
  544. /// </summary>
  545. /// <param name="e"></param>
  546. protected override void OnMouseMove(MouseEventArgs e)
  547. {
  548. base.OnMouseMove(e);
  549. }
  550. /// <summary>
  551. /// 鼠标按下
  552. /// </summary>
  553. /// <param name="e"></param>
  554. protected override void OnMouseDown(MouseEventArgs e)
  555. {
  556. base.OnMouseDown(e);
  557. }
  558. /// <summary>
  559. /// 鼠标抬起
  560. /// </summary>
  561. /// <param name="e"></param>
  562. protected override void OnMouseUp(MouseEventArgs e)
  563. {
  564. base.OnMouseUp(e);
  565. }
  566. #endregion
  567. #endregion
  568. #region 重写方法
  569. /// <summary>
  570. /// 处理 System.Windows.Forms.CheckedListBox 控件从顶级窗口中接收的命令消息
  571. /// </summary>
  572. /// <param name="m">顶级窗口发送到此控件的 System.Windows.Forms.Message</param>
  573. [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  574. protected override void WmReflectCommand(ref Message m)
  575. {
  576. int n = (int)((long)m.WParam);
  577. n = n >> 16 & 65535;
  578. switch (n)
  579. {
  580. case 1:
  581. case 2:
  582. int selectedIndex = this.SelectedIndex;
  583. if (selectedIndex < 0 || selectedIndex >= this.Items.Count)
  584. {
  585. base.WmReflectCommand(ref m);
  586. return;
  587. }
  588. CheckState checkedState = this.GetItemCheckState(selectedIndex);
  589. base.WmReflectCommand(ref m);
  590. CheckState newCheckValue = this.GetItemCheckState(selectedIndex);
  591. if (checkedState != newCheckValue)
  592. {
  593. this.CheckOnItemChecked();
  594. ItemCheckedEventArgs itemCheckEventArgs =
  595. new ItemCheckedEventArgs(selectedIndex, newCheckValue, checkedState);
  596. this.OnItemChecked(itemCheckEventArgs);
  597. }
  598. return;
  599. default:
  600. base.WmReflectCommand(ref m);
  601. return;
  602. }
  603. }
  604. /// <summary>
  605. /// 处理 Windows 消息
  606. /// </summary>
  607. /// <param name="m">要处理的 Windows System.Windows.Forms.Message</param>
  608. protected override void WndProc(ref Message m)
  609. {
  610. base.WndProc(ref m);
  611. if (m.Msg == (int)WindowsMessage.WM_PAINT ||
  612. m.Msg == (int)WindowsMessage.WM_NCPAINT ||
  613. m.Msg == (int)WindowsMessage.WM_CTLCOLOREDIT)
  614. {
  615. //this.WmBorderPaint(ref m);
  616. BorderColorPaint.WmBorderPaint(this._borderColor, this.Width, this.Height, ref m);
  617. }
  618. }
  619. #endregion
  620. #region 公有方法
  621. /// <summary>
  622. /// 获取指定项的成员属性的值
  623. /// </summary>
  624. /// <param name="item">项</param>
  625. /// <returns>值</returns>
  626. public virtual object GetItemValue(object item)
  627. {
  628. if (this.DataManager != null)
  629. {
  630. string dataMember = this.ValueMember;
  631. if (dataMember == null)
  632. {
  633. dataMember = string.Empty;
  634. }
  635. int num = dataMember.LastIndexOf(Constant.S_POINT);
  636. if (num != -1)
  637. {
  638. dataMember = dataMember.Substring(num + 1);
  639. }
  640. return this.FilterItemOnProperty(item, dataMember);
  641. }
  642. return null;
  643. }
  644. /// <summary>
  645. /// 获取选中项的文本表示形式
  646. /// </summary>
  647. /// <returns>选中项的文本</returns>
  648. public virtual List<string> GetCheckedItemTexts()
  649. {
  650. List<string> checkedTexts = new List<string>();
  651. foreach (object item in this.CheckedItems)
  652. {
  653. checkedTexts.Add(this.GetItemText(item));
  654. }
  655. return checkedTexts;
  656. }
  657. /// <summary>
  658. /// 获取选中项的成员属性的值
  659. /// </summary>
  660. /// <returns>选中项的值</returns>
  661. public virtual List<object> GetCheckedItemValues()
  662. {
  663. return this.GetCheckedItemValues<object>();
  664. }
  665. /// <summary>
  666. /// 获取选中项的成员属性的值
  667. /// </summary>
  668. /// <typeparam name="T">属性值的类型</typeparam>
  669. /// <returns>选中项的值</returns>
  670. public virtual List<T> GetCheckedItemValues<T>()
  671. {
  672. List<T> checkedValues = new List<T>();
  673. foreach (object item in this.CheckedItems)
  674. {
  675. checkedValues.Add((T)this.GetItemValue(item));
  676. }
  677. return checkedValues;
  678. }
  679. /// <summary>
  680. /// 设定全部项的复选状态
  681. /// </summary>
  682. /// <param name="value">若要将该项设置为选中,则为 true;否则为 false</param>
  683. public virtual void SetItemsChecked(bool value)
  684. {
  685. for (int i = 0; i < this.Items.Count; i++)
  686. {
  687. this.SetItemChecked(value, i);
  688. }
  689. }
  690. /// <summary>
  691. /// 获取全部项的复选状态
  692. /// </summary>
  693. /// <returns>选中状态</returns>
  694. public virtual CheckState GetItemsCheckState()
  695. {
  696. int checkedItemsCount = this.CheckedItems.Count;
  697. if (checkedItemsCount == 0)
  698. {
  699. return CheckState.Unchecked;
  700. }
  701. int itemsCount = this.Items.Count;
  702. if (checkedItemsCount != itemsCount)
  703. {
  704. return CheckState.Indeterminate;
  705. }
  706. if (!this.ThreeDCheckBoxes)
  707. {
  708. return CheckState.Checked;
  709. }
  710. for (int i = 0; i < this.CheckedItems.Count; i++)
  711. {
  712. CheckState cs = this.GetItemCheckState(i);
  713. if (cs == CheckState.Indeterminate)
  714. {
  715. return CheckState.Indeterminate;
  716. }
  717. }
  718. return CheckState.Checked;
  719. }
  720. /// <summary>
  721. /// 设定指定项的复选状态
  722. /// </summary>
  723. /// <param name="value">若要将该项设置为选中,则为 true;否则为 false</param>
  724. /// <param name="items">要为其设置复选状态的项</param>
  725. public virtual void SetItemCheckedByItem(bool value, params object[] items)
  726. {
  727. foreach (object item in items)
  728. {
  729. for (int i = 0; i < this.Items.Count; i++)
  730. {
  731. object itemInner = this.Items[i];
  732. if (itemInner == item)
  733. {
  734. this.SetItemChecked(value, i);
  735. return;
  736. }
  737. }
  738. }
  739. }
  740. /// <summary>
  741. /// 设定指定值的项的复选状态
  742. /// </summary>
  743. /// <param name="value">若要将该项设置为选中,则为 true;否则为 false</param>
  744. /// <param name="itemValues">要为其设置复选状态的项的值</param>
  745. public virtual void SetItemCheckedByValue(bool value, params object[] itemValues)
  746. {
  747. foreach (object itemValue in itemValues)
  748. {
  749. for (int i = 0; i < this.Items.Count; i++)
  750. {
  751. object itemValueInner = this.GetItemValue(this.Items[i]);
  752. if ((itemValueInner == null && itemValue == null) ||
  753. (itemValueInner != null && itemValueInner.Equals(itemValue)))
  754. {
  755. this.SetItemChecked(value, i);
  756. break;
  757. }
  758. }
  759. }
  760. }
  761. /// <summary>
  762. /// 设定指定值的项的复选状态
  763. /// </summary>
  764. /// <param name="value">若要将该项设置为选中,则为 true;否则为 false</param>
  765. /// <param name="itemValues">要为其设置复选状态的项的值</param>
  766. public virtual void SetItemCheckedByValueID(bool value, params string[] itemValues)
  767. {
  768. foreach (string itemValue in itemValues)
  769. {
  770. for (int i = 0; i < this.Items.Count; i++)
  771. {
  772. object itemValueInner = this.GetItemValue(this.Items[i]);
  773. if ((itemValueInner == null && itemValue == null) ||
  774. (itemValue != null && itemValue == itemValueInner + ""))
  775. {
  776. this.SetItemChecked(value, i);
  777. break;
  778. }
  779. }
  780. }
  781. }
  782. /// <summary>
  783. /// 设定指定索引处的项目选中或取消
  784. /// </summary>
  785. /// <param name="value">若要将该项设置为选中,则为 true;否则为 false</param>
  786. /// <param name="indexs">要为其设置复选状态的项的索引</param>
  787. public void SetItemChecked(bool value, params int[] indexs)
  788. {
  789. foreach (int index in indexs)
  790. {
  791. //this.SetItemCheckState(index, value ? CheckState.Checked : CheckState.Unchecked);
  792. // 响应OnItemChecked事件
  793. this.SetItemChecked(index, value);
  794. }
  795. }
  796. /// <summary>
  797. /// 设置指定索引处项的复选状态
  798. /// </summary>
  799. /// <param name="index">要为其设置状态的项的索引</param>
  800. /// <param name="value">若要将该项设置为选中,则为 true;否则为 false</param>
  801. public new void SetItemChecked(int index, bool value)
  802. {
  803. bool checkedValue = this.GetItemChecked(index);
  804. base.SetItemChecked(index, value);
  805. if (value != checkedValue)
  806. {
  807. this.CheckOnItemChecked();
  808. ItemCheckedEventArgs itemCheckEventArgs =
  809. new ItemCheckedEventArgs(index,
  810. value ? CheckState.Checked : CheckState.Unchecked,
  811. checkedValue ? CheckState.Checked : CheckState.Unchecked);
  812. this.OnItemChecked(itemCheckEventArgs);
  813. }
  814. }
  815. /// <summary>
  816. /// 设置指定索引处项的复选状态
  817. /// </summary>
  818. /// <param name="index">要为其设置状态的项的索引</param>
  819. /// <param name="value">System.Windows.Forms.CheckState 值之一</param>
  820. public new void SetItemCheckState(int index, CheckState value)
  821. {
  822. CheckState checkedState = this.GetItemCheckState(index);
  823. base.SetItemCheckState(index, value);
  824. if (value != checkedState)
  825. {
  826. this.CheckOnItemChecked();
  827. ItemCheckedEventArgs itemCheckEventArgs =
  828. new ItemCheckedEventArgs(index, value, checkedState);
  829. this.OnItemChecked(itemCheckEventArgs);
  830. }
  831. }
  832. /// <summary>
  833. /// 选择下一个Item
  834. /// </summary>
  835. /// <param name="clearSelect">是否能选择空</param>
  836. public void SelectNextItem(bool clearSelect = true)
  837. {
  838. int boxItemCount = this.Items.Count;
  839. if (boxItemCount < 1)
  840. {
  841. return;
  842. }
  843. int boxSelectedIndex = this.SelectedIndex;
  844. boxSelectedIndex++;
  845. if (boxSelectedIndex >= boxItemCount)
  846. {
  847. if (this._mustInput || !clearSelect)
  848. {
  849. boxSelectedIndex = 0;
  850. }
  851. else
  852. {
  853. boxSelectedIndex = -1;
  854. }
  855. }
  856. if (boxSelectedIndex < 0)
  857. {
  858. this.SelectedIndex = 0;
  859. this.ClearSelected();
  860. }
  861. else
  862. {
  863. this.SelectedIndex = boxSelectedIndex;
  864. }
  865. }
  866. /// <summary>
  867. /// 选择上一个Item
  868. /// </summary>
  869. /// <param name="clearSelect">是否能选择空</param>
  870. public void SelectPrevItem(bool clearSelect = true)
  871. {
  872. int boxItemCount = this.Items.Count;
  873. if (boxItemCount < 1)
  874. {
  875. return;
  876. }
  877. int boxSelectedIndex = this.SelectedIndex;
  878. boxSelectedIndex--;
  879. if (boxSelectedIndex < -1 ||
  880. ((this._mustInput || !clearSelect) && boxSelectedIndex < 0))
  881. {
  882. boxSelectedIndex = boxItemCount - 1;
  883. }
  884. if (boxSelectedIndex < 0)
  885. {
  886. this.ClearSelected();
  887. }
  888. else
  889. {
  890. this.SelectedIndex = boxSelectedIndex;
  891. }
  892. }
  893. #endregion
  894. #region 保护方法
  895. /// <summary>
  896. /// 重置全部项的复选状态(必选或单选)
  897. /// </summary>
  898. internal protected virtual void ResetMustOrSimpleChecked()
  899. {
  900. if (this._mustInput && this.CheckedIndices.Count == 0 && this.Items.Count > 0)
  901. {
  902. int index = this.SelectedIndex < 0 ? 0 : this.SelectedIndex;
  903. this.SetItemChecked(index, true);
  904. return;
  905. }
  906. if (this._simpleChecked && this.CheckedIndices.Count > 1)
  907. {
  908. this._isSimpleChecking = true;
  909. try
  910. {
  911. int index = this.CheckedIndices.Contains(this.SelectedIndex) ?
  912. this.SelectedIndex : this.CheckedIndices[0];
  913. foreach (int checkedIndex in this.CheckedIndices)
  914. {
  915. if (checkedIndex != index)
  916. {
  917. this.SetItemChecked(checkedIndex, false);
  918. }
  919. }
  920. }
  921. finally
  922. {
  923. this._isSimpleChecking = false;
  924. }
  925. return;
  926. }
  927. }
  928. #endregion
  929. #region 私有方法
  930. /// <summary>
  931. /// 当ItemChecked事件发生时,验证Error。
  932. /// </summary>
  933. private void CheckOnItemChecked()
  934. {
  935. if (this._mustInput)
  936. {
  937. if (this._inputCount != this.CheckedItems.Count)
  938. {
  939. this._inputCount = this.CheckedItems.Count;
  940. if (this._inputCount > 0)
  941. {
  942. this.ClearError();
  943. }
  944. else
  945. {
  946. if (this.SelectedIndex > 0)
  947. {
  948. this.SetItemChecked(this.SelectedIndex, true);
  949. return;
  950. }
  951. if (this.Items.Count > 0)
  952. {
  953. this.SetItemChecked(0, true);
  954. return;
  955. }
  956. this.SetError(true, ControlErrorCode.DKC_0001, this._itemName);
  957. }
  958. }
  959. }
  960. }
  961. /// <summary>
  962. /// 使父控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向父控件发送绘制消息。
  963. /// </summary>
  964. private void InvalidateBorder()
  965. {
  966. Color? borderColor = BorderColorPaint.GetBorderColor(this as IDataVerifiable, this._entered, this._mouseOver);
  967. if (borderColor != this._borderColor)
  968. {
  969. this._borderColor = borderColor;
  970. if (this.Parent == null)
  971. {
  972. this.Invalidate();
  973. }
  974. else
  975. {
  976. this.Parent.Invalidate(this.Bounds, true);
  977. }
  978. }
  979. }
  980. #endregion
  981. #region IDataVerifiable 成员
  982. #region 成员变量
  983. /// <summary>
  984. /// 显示边框颜色
  985. /// </summary>
  986. private bool _showBorderColor = true;
  987. /// <summary>
  988. /// 控件的项目名
  989. /// </summary>
  990. private string _itemName = null;
  991. /// <summary>
  992. /// 控件是否是必须输入项目
  993. /// </summary>
  994. private bool _mustInput = false;
  995. /// <summary>
  996. /// 控件在验证输入错误时,如何提示
  997. /// </summary>
  998. private InputErrorAlert _errorAlert = InputErrorAlert.Validated;
  999. /// <summary>
  1000. /// 是否显示必须输入项目的提示
  1001. /// </summary>
  1002. private bool _showMustInputAlert = true;
  1003. /// <summary>
  1004. /// 验证不通过时,焦点能否离开
  1005. /// </summary>
  1006. private bool _canLostFocusOnError = true;
  1007. /// <summary>
  1008. /// 验证是否有错误
  1009. /// </summary>
  1010. private bool _hasError = false;
  1011. /// <summary>
  1012. /// 是否自定义错误
  1013. /// </summary>
  1014. private bool _hasCustomerError = false;
  1015. /// <summary>
  1016. /// 错误编码
  1017. /// </summary>
  1018. private ControlErrorCode _errorCode = ControlErrorCode.DKC_0000;
  1019. /// <summary>
  1020. /// 错误消息
  1021. /// </summary>
  1022. private string _errorMessage = null;
  1023. /// <summary>
  1024. /// 自定义错误消息
  1025. /// </summary>
  1026. private string _customerErrorMessage = null;
  1027. #endregion
  1028. #region 属性
  1029. /// <summary>
  1030. /// 获取或设置控件是否显示边框颜色。
  1031. /// </summary>
  1032. [Description("获取或设置控件是否显示边框颜色。"), Category("IDataVerifiable")]
  1033. [DefaultValue(true)]
  1034. public bool ShowBorderColor
  1035. {
  1036. get
  1037. {
  1038. return this._showBorderColor;
  1039. }
  1040. set
  1041. {
  1042. if (this._showBorderColor != value)
  1043. {
  1044. this._showBorderColor = value;
  1045. this.InvalidateBorder();
  1046. }
  1047. }
  1048. }
  1049. /// <summary>
  1050. /// 获取或设置控件的项目名
  1051. /// </summary>
  1052. [Description("获取或设置控件的项目名。"), Category("IDataVerifiable")]
  1053. [DefaultValue(null)]
  1054. public string CDItemName
  1055. {
  1056. get
  1057. {
  1058. return this._itemName;
  1059. }
  1060. set
  1061. {
  1062. this._itemName = value;
  1063. }
  1064. }
  1065. /// <summary>
  1066. /// 获取或设置控件是否必须选中项目。
  1067. /// </summary>
  1068. [Description("获取或设置控件是否必须选中项目。"), Category("IDataVerifiable")]
  1069. [DefaultValue(false)]
  1070. public bool MustInput
  1071. {
  1072. get
  1073. {
  1074. return this._mustInput;
  1075. }
  1076. set
  1077. {
  1078. if (this._mustInput != value)
  1079. {
  1080. this._mustInput = value;
  1081. this.ResetMustOrSimpleChecked();
  1082. this.ValidateData();
  1083. if (this._mustInput && this._showMustInputAlert)
  1084. {
  1085. this.InvalidateBorder();
  1086. }
  1087. }
  1088. }
  1089. }
  1090. /// <summary>
  1091. /// 获取或设置控件是否必须选中项目。
  1092. /// </summary>
  1093. [Description("获取或设置控件在验证输入错误时,如何提示。"), Category("IDataVerifiable")]
  1094. [DefaultValue(typeof(InputErrorAlert), "Validated")]
  1095. public InputErrorAlert InputErrorAlert
  1096. {
  1097. get
  1098. {
  1099. return this._errorAlert;
  1100. }
  1101. set
  1102. {
  1103. if (this._errorAlert != value)
  1104. {
  1105. this._errorAlert = value;
  1106. this.InvalidateBorder();
  1107. }
  1108. }
  1109. }
  1110. /// <summary>
  1111. /// 获取或设置控件是否显示必须输入项目提示
  1112. /// </summary>
  1113. [Description("获取或设置控件是否显示必须输入项目提示。"), Category("IDataVerifiable")]
  1114. [DefaultValue(true)]
  1115. public bool ShowMustInputAlert
  1116. {
  1117. get
  1118. {
  1119. return this._showMustInputAlert;
  1120. }
  1121. set
  1122. {
  1123. if (this._showMustInputAlert != value)
  1124. {
  1125. this._showMustInputAlert = value;
  1126. this.InvalidateBorder();
  1127. }
  1128. }
  1129. }
  1130. /// <summary>
  1131. /// 获取或设置当验证不通过时,控件是否可以失去焦点
  1132. /// </summary>
  1133. [Description("获取或设置当验证不通过时,控件是否可以失去焦点。"), Category("IDataVerifiable")]
  1134. [DefaultValue(true)]
  1135. public bool CanLostFocusOnError
  1136. {
  1137. get
  1138. {
  1139. return this._canLostFocusOnError;
  1140. }
  1141. set
  1142. {
  1143. this._canLostFocusOnError = value;
  1144. }
  1145. }
  1146. /// <summary>
  1147. /// 获取控件校验时是否有错误
  1148. /// </summary>
  1149. [Description("获取控件校验时是否有错误。"), Category("IDataVerifiable")]
  1150. [DefaultValue(false)]
  1151. public bool HasError
  1152. {
  1153. get
  1154. {
  1155. return this._hasCustomerError || this._hasError;
  1156. }
  1157. }
  1158. /// <summary>
  1159. /// 获取控件校验时的错误编码
  1160. /// </summary>
  1161. [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")]
  1162. [DefaultValue(typeof(ControlErrorCode), "DKC_0000")]
  1163. public ControlErrorCode ErrorCode
  1164. {
  1165. get
  1166. {
  1167. return this._hasCustomerError ? ControlErrorCode.DKC_C001 : this._errorCode;
  1168. }
  1169. }
  1170. /// <summary>
  1171. /// 获取控件校验时的错误消息
  1172. /// </summary>
  1173. [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")]
  1174. [DefaultValue(null)]
  1175. public string ErrorMessage
  1176. {
  1177. get
  1178. {
  1179. return this._hasCustomerError ? this._customerErrorMessage : this._errorMessage;
  1180. }
  1181. }
  1182. #endregion
  1183. #region 公有方法
  1184. /// <summary>
  1185. /// 设置自定义错误
  1186. /// </summary>
  1187. /// <param name="hasError">输入是否有错误</param>
  1188. /// <param name="errorMessage">错误消息</param>
  1189. public virtual void SetCustomerError(bool hasError, string errorMessage)
  1190. {
  1191. if (this._hasCustomerError != hasError ||
  1192. this._customerErrorMessage != errorMessage)
  1193. {
  1194. this._hasCustomerError = hasError;
  1195. this._customerErrorMessage = errorMessage;
  1196. this.OnHasErrorChanged(EventArgs.Empty);
  1197. this.InvalidateBorder();
  1198. }
  1199. }
  1200. /// <summary>
  1201. /// 清除自定义错误
  1202. /// </summary>
  1203. public virtual void ClearCustomerError()
  1204. {
  1205. this.SetCustomerError(false, null);
  1206. }
  1207. /// <summary>
  1208. /// 验证输入内容
  1209. /// </summary>
  1210. /// <returns>验证结果</returns>
  1211. public virtual bool ValidateData()
  1212. {
  1213. if (this._mustInput && this.CheckedItems.Count == 0)
  1214. {
  1215. this.SetError(true, ControlErrorCode.DKC_0001, this._itemName);
  1216. return false;
  1217. }
  1218. this.ClearError();
  1219. return true;
  1220. }
  1221. /// <summary>
  1222. /// 清除输入项
  1223. /// </summary>
  1224. public virtual void ClearValue()
  1225. {
  1226. this.SetItemsChecked(false);
  1227. }
  1228. #endregion
  1229. #region 保护方法
  1230. /// <summary>
  1231. /// 设置验证不通过错误
  1232. /// </summary>
  1233. /// <param name="hasError">是否有错误</param>
  1234. /// <param name="code">错误编码</param>
  1235. /// <param name="args">设置格式的对象</param>
  1236. protected void SetError(bool hasError, ControlErrorCode code, params object[] args)
  1237. {
  1238. if (this._hasError != hasError ||
  1239. this._errorCode != code)
  1240. {
  1241. this._hasError = hasError;
  1242. this._errorCode = code;
  1243. if (args != null && args.Length > 0)
  1244. {
  1245. this._errorMessage = string.Format(code.GetDescription(), args);
  1246. }
  1247. else
  1248. {
  1249. this._errorMessage = code.GetDescription();
  1250. }
  1251. this.OnHasErrorChanged(EventArgs.Empty);
  1252. this.InvalidateBorder();
  1253. }
  1254. }
  1255. /// <summary>
  1256. /// 清除验证不通过错误
  1257. /// </summary>
  1258. protected void ClearError()
  1259. {
  1260. this.SetError(false, ControlErrorCode.DKC_0000);
  1261. }
  1262. #endregion
  1263. #endregion
  1264. #region IAsyncControl 成员
  1265. #region 成员变量
  1266. /// <summary>
  1267. /// 异步处理开始时,控件状态
  1268. /// </summary>
  1269. private bool _asyncBeginStatus = false;
  1270. private bool _asyncBeginFocused = false;
  1271. #endregion
  1272. #region 公有方法
  1273. /// <summary>
  1274. /// 开始异步处理
  1275. /// </summary>
  1276. /// <param name="doFocus">是否处理焦点</param>
  1277. public virtual void BeginAsync(ref bool doFocus)
  1278. {
  1279. this._asyncBeginFocused = false;
  1280. if (doFocus && this.Focused)
  1281. {
  1282. this._asyncBeginFocused = true;
  1283. doFocus = false;
  1284. }
  1285. this._asyncBeginStatus = this.Enabled;
  1286. this.Enabled = false;
  1287. }
  1288. /// <summary>
  1289. /// 结束异步处理
  1290. /// </summary>
  1291. public virtual void EndAsync()
  1292. {
  1293. this.Enabled = this._asyncBeginStatus;
  1294. if (this._asyncBeginFocused)
  1295. {
  1296. this.Focus();
  1297. }
  1298. }
  1299. #endregion
  1300. #endregion
  1301. }
  1302. }