LstListBox.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. 
  2. using System;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Drawing.Drawing2D;
  6. using System.Windows.Forms;
  7. using Dongke.WinForm.Utilities;
  8. namespace Dongke.WinForm.Controls
  9. {
  10. /// <summary>
  11. /// 标准列表控件
  12. /// </summary>
  13. [ToolboxBitmap(typeof(ListBox))]
  14. public class LstListBox : ListBox, IDKControl, IDataVerifiable, IAsyncControl
  15. {
  16. #region 事件声明
  17. #region HasErrorChanged
  18. /// <summary>
  19. /// 当 HasError 属性的值更改时发生。
  20. /// </summary>
  21. private static readonly object EventHasErrorChanged = new object();
  22. /// <summary>
  23. /// 当 HasError 属性的值更改时发生。
  24. /// </summary>
  25. [Description("当 HasError 属性的值更改时发生。"), Category("CustomerEx")]
  26. public event EventHandler HasErrorChanged
  27. {
  28. add
  29. {
  30. base.Events.AddHandler(EventHasErrorChanged, value);
  31. }
  32. remove
  33. {
  34. base.Events.RemoveHandler(EventHasErrorChanged, value);
  35. }
  36. }
  37. #endregion
  38. #endregion
  39. #region 成员变量
  40. /// <summary>
  41. /// 焦点是否进入控件
  42. /// </summary>
  43. private bool _entered = false;
  44. /// <summary>
  45. /// 鼠标是否进入控件
  46. /// </summary>
  47. private bool _mouseOver = false;
  48. /// <summary>
  49. /// 边框颜色
  50. /// </summary>
  51. private Color? _borderColor = null;
  52. /// <summary>
  53. /// 上次选中项个数
  54. /// </summary>
  55. private int _inputCount = -1;
  56. #endregion
  57. #region 构造函数
  58. /// <summary>
  59. /// 标准列表控件
  60. /// </summary>
  61. public LstListBox()
  62. {
  63. this.FormattingEnabled = false;
  64. CommonSetting.InitControls(this);
  65. }
  66. #endregion
  67. #region 属性
  68. /// <summary>
  69. /// 获取一个值,该值指示控件是否有输入焦点。
  70. /// </summary>
  71. [DefaultValue(false)]
  72. [Browsable(false)]
  73. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  74. [EditorBrowsable(EditorBrowsableState.Advanced)]
  75. public virtual bool Entered
  76. {
  77. get
  78. {
  79. return this._entered;
  80. }
  81. protected set
  82. {
  83. if (this._entered != value)
  84. {
  85. this._entered = value;
  86. this.InvalidateBorder();
  87. }
  88. }
  89. }
  90. /// <summary>
  91. /// 获取一个值,该值指示鼠标是否在控件上方。
  92. /// </summary>
  93. [DefaultValue(false)]
  94. [Browsable(false)]
  95. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  96. [EditorBrowsable(EditorBrowsableState.Advanced)]
  97. public virtual bool MouseOver
  98. {
  99. get
  100. {
  101. return this._mouseOver;
  102. }
  103. protected set
  104. {
  105. if (this._mouseOver != value)
  106. {
  107. this._mouseOver = value;
  108. this.InvalidateBorder();
  109. }
  110. }
  111. }
  112. #endregion
  113. #region 重写属性
  114. /// <summary>
  115. /// 获取或设置在 System.Windows.Forms.ListBox 中选择项所用的方法
  116. /// </summary>
  117. public override SelectionMode SelectionMode
  118. {
  119. get
  120. {
  121. return base.SelectionMode;
  122. }
  123. set
  124. {
  125. if (value == SelectionMode.None && this._mustInput)
  126. {
  127. //value = SelectionMode.One;
  128. return;
  129. }
  130. base.SelectionMode = value;
  131. }
  132. }
  133. /// <summary>
  134. /// 获取或设置控件中项的高度。
  135. /// </summary>
  136. [DefaultValue(12)]
  137. public override int ItemHeight
  138. {
  139. get
  140. {
  141. return base.ItemHeight;
  142. }
  143. set
  144. {
  145. base.ItemHeight = value;
  146. }
  147. }
  148. /// <summary>
  149. /// 获取或设置控件的数据源
  150. /// </summary>
  151. [Description("获取或设置控件的数据源。"), Category("CustomerEx")]
  152. [DefaultValue(null)]
  153. [Browsable(true)]
  154. public new object DataSource
  155. {
  156. get
  157. {
  158. return base.DataSource;
  159. }
  160. set
  161. {
  162. base.DataSource = value;
  163. if (!this._mustInput)
  164. {
  165. this.SelectedIndex = -1;
  166. }
  167. }
  168. }
  169. #endregion
  170. #region 重写事件
  171. #region 属性改变
  172. /// <summary>
  173. /// 引发 HasErrorChanged 事件
  174. /// </summary>
  175. /// <param name="e">包含事件数据的 EventArgs</param>
  176. protected virtual void OnHasErrorChanged(EventArgs e)
  177. {
  178. EventHandler eventHandler = (EventHandler)base.Events[EventHasErrorChanged];
  179. if (eventHandler != null)
  180. {
  181. eventHandler(this, e);
  182. }
  183. }
  184. #endregion
  185. #region 行为事件
  186. /// <summary>
  187. /// 选择项目改变
  188. /// </summary>
  189. /// <param name="e"></param>
  190. protected override void OnSelectedIndexChanged(EventArgs e)
  191. {
  192. this.CheckOnSelectedIndexChanged();
  193. base.OnSelectedIndexChanged(e);
  194. }
  195. #endregion
  196. #region 键盘事件
  197. /// <summary>
  198. /// 键盘点击
  199. /// </summary>
  200. /// <param name="e"></param>
  201. protected override void OnKeyDown(KeyEventArgs e)
  202. {
  203. base.OnKeyDown(e);
  204. if (this.SelectedIndex < 1 && (e.KeyCode == Keys.Up || e.KeyCode == Keys.Left))
  205. {
  206. this.SelectPrevItem();
  207. e.Handled = true;
  208. return;
  209. }
  210. if (this.SelectedIndex == this.Items.Count - 1 && (e.KeyCode == Keys.Down || e.KeyCode == Keys.Right))
  211. {
  212. this.SelectNextItem();
  213. e.Handled = true;
  214. return;
  215. }
  216. }
  217. #endregion
  218. #region 焦点事件
  219. /// <summary>
  220. /// 输入焦点进入控件
  221. /// </summary>
  222. /// <param name="e"></param>
  223. protected override void OnEnter(EventArgs e)
  224. {
  225. this.Entered = true;
  226. base.OnEnter(e);
  227. }
  228. /// <summary>
  229. /// 获得焦点
  230. /// </summary>
  231. /// <param name="e"></param>
  232. protected override void OnGotFocus(EventArgs e)
  233. {
  234. base.OnGotFocus(e);
  235. }
  236. /// <summary>
  237. /// 失去焦点
  238. /// </summary>
  239. /// <param name="e"></param>
  240. protected override void OnLostFocus(EventArgs e)
  241. {
  242. base.OnLostFocus(e);
  243. }
  244. /// <summary>
  245. /// 输入焦点离开控件
  246. /// </summary>
  247. /// <param name="e"></param>
  248. protected override void OnLeave(EventArgs e)
  249. {
  250. base.OnLeave(e);
  251. //this.Entered = false;
  252. }
  253. /// <summary>
  254. /// 控件正在验证
  255. /// </summary>
  256. /// <param name="e"></param>
  257. protected override void OnValidating(CancelEventArgs e)
  258. {
  259. base.OnValidating(e);
  260. if (this.HasError && !this._canLostFocusOnError)
  261. {
  262. e.Cancel = true;
  263. }
  264. }
  265. /// <summary>
  266. /// 控件完成验证
  267. /// </summary>
  268. /// <param name="e"></param>
  269. protected override void OnValidated(EventArgs e)
  270. {
  271. this.Entered = false;
  272. base.OnValidated(e);
  273. }
  274. #endregion
  275. #region 鼠标事件
  276. /// <summary>
  277. /// 鼠标进入控件
  278. /// </summary>
  279. /// <param name="e"></param>
  280. protected override void OnMouseEnter(EventArgs e)
  281. {
  282. this.MouseOver = true;
  283. base.OnMouseEnter(e);
  284. }
  285. /// <summary>
  286. /// 鼠标离开控件
  287. /// </summary>
  288. /// <param name="e"></param>
  289. protected override void OnMouseLeave(EventArgs e)
  290. {
  291. base.OnMouseLeave(e);
  292. this.MouseOver = false;
  293. }
  294. /// <summary>
  295. /// 鼠标移动
  296. /// </summary>
  297. /// <param name="e"></param>
  298. protected override void OnMouseMove(MouseEventArgs e)
  299. {
  300. base.OnMouseMove(e);
  301. }
  302. /// <summary>
  303. /// 鼠标按下
  304. /// </summary>
  305. /// <param name="e"></param>
  306. protected override void OnMouseDown(MouseEventArgs e)
  307. {
  308. base.OnMouseDown(e);
  309. }
  310. /// <summary>
  311. /// 鼠标抬起
  312. /// </summary>
  313. /// <param name="e"></param>
  314. protected override void OnMouseUp(MouseEventArgs e)
  315. {
  316. base.OnMouseUp(e);
  317. }
  318. #endregion
  319. #endregion
  320. #region 重写方法
  321. /// <summary>
  322. /// 处理 Windows 消息
  323. /// </summary>
  324. /// <param name="m">要处理的 Windows System.Windows.Forms.Message</param>
  325. protected override void WndProc(ref Message m)
  326. {
  327. base.WndProc(ref m);
  328. if (m.Msg == (int)WindowsMessage.WM_PAINT ||
  329. m.Msg == (int)WindowsMessage.WM_NCPAINT ||
  330. m.Msg == (int)WindowsMessage.WM_CTLCOLOREDIT)
  331. {
  332. //this.WmBorderPaint(ref m);
  333. BorderColorPaint.WmBorderPaint(this._borderColor, this.Width, this.Height, ref m);
  334. }
  335. }
  336. #endregion
  337. #region 公有方法
  338. /// <summary>
  339. /// 获取指定项的成员属性的值
  340. /// </summary>
  341. /// <param name="item">项</param>
  342. /// <returns>值</returns>
  343. public virtual object GetItemValue(object item)
  344. {
  345. if (this.DataManager != null)
  346. {
  347. string dataMember = this.ValueMember;
  348. if (dataMember == null)
  349. {
  350. dataMember = string.Empty;
  351. }
  352. int num = dataMember.LastIndexOf(Constant.S_POINT);
  353. if (num != -1)
  354. {
  355. dataMember = dataMember.Substring(num + 1);
  356. }
  357. return this.FilterItemOnProperty(item, dataMember);
  358. }
  359. return null;
  360. }
  361. /// <summary>
  362. /// 选择下一个Item
  363. /// </summary>
  364. /// <param name="clearSelect">是否能选择空</param>
  365. public void SelectNextItem(bool clearSelect = true)
  366. {
  367. int boxItemCount = this.Items.Count;
  368. if (boxItemCount < 1)
  369. {
  370. return;
  371. }
  372. int boxSelectedIndex = this.SelectedIndex;
  373. boxSelectedIndex++;
  374. if (boxSelectedIndex >= boxItemCount)
  375. {
  376. if (this._mustInput || !clearSelect)
  377. {
  378. boxSelectedIndex = 0;
  379. }
  380. else
  381. {
  382. boxSelectedIndex = -1;
  383. }
  384. }
  385. if (boxSelectedIndex < 0)
  386. {
  387. this.SelectedIndex = 0;
  388. this.ClearSelected();
  389. }
  390. else
  391. {
  392. this.SelectedIndex = boxSelectedIndex;
  393. }
  394. }
  395. /// <summary>
  396. /// 选择上一个Item
  397. /// </summary>
  398. /// <param name="clearSelect">是否能选择空</param>
  399. public void SelectPrevItem(bool clearSelect = true)
  400. {
  401. int boxItemCount = this.Items.Count;
  402. if (boxItemCount < 1)
  403. {
  404. return;
  405. }
  406. int boxSelectedIndex = this.SelectedIndex;
  407. boxSelectedIndex--;
  408. if (boxSelectedIndex < -1 ||
  409. ((this._mustInput || !clearSelect) && boxSelectedIndex < 0))
  410. {
  411. boxSelectedIndex = boxItemCount - 1;
  412. }
  413. if (boxSelectedIndex < 0)
  414. {
  415. this.ClearSelected();
  416. }
  417. else
  418. {
  419. this.SelectedIndex = boxSelectedIndex;
  420. }
  421. }
  422. /*
  423. /// <summary>
  424. /// 确定指定的键是常规输入键还是需要预处理的特殊键
  425. /// </summary>
  426. /// <param name="keyData">System.Windows.Forms.Keys 值之一。</param>
  427. /// <returns>如果指定的键是常规输入键,则为 true;否则为 false。</returns>
  428. public virtual new bool IsInputKey(Keys keyData)
  429. {
  430. return base.IsInputKey(keyData);
  431. }
  432. /// <summary>
  433. /// 确定一个字符是否是控件可识别的输入字符
  434. /// </summary>
  435. /// <param name="charCode">要测试的字符。</param>
  436. /// <returns>如果字符应直接发送到控件且不必经过预处理,则为 true;否则为 false。</returns>
  437. public virtual new bool IsInputChar(char charCode)
  438. {
  439. return base.IsInputChar(charCode);
  440. }
  441. */
  442. #endregion
  443. #region 保护方法
  444. /*
  445. /// <summary>
  446. /// 处理重绘控件边框的 Windows 消息
  447. /// </summary>
  448. /// <param name="m"></param>
  449. protected virtual void WmBorderPaint(Color? borderColor, ref Message m)
  450. {
  451. if (borderColor.HasValue)
  452. {
  453. IntPtr hDC = WindowsAPI.GetWindowDC(m.HWnd);
  454. if (hDC.ToInt32() == 0)
  455. {
  456. return;
  457. }
  458. // 绘制
  459. using (Pen pen = new Pen(borderColor.Value))
  460. {
  461. using (Graphics g = Graphics.FromHdc(hDC))
  462. {
  463. g.SmoothingMode = SmoothingMode.AntiAlias;
  464. g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
  465. }
  466. }
  467. // 释放
  468. WindowsAPI.ReleaseDC(m.HWnd, hDC);
  469. }
  470. }
  471. */
  472. #endregion
  473. #region 私有方法
  474. /// <summary>
  475. /// 当SelectedIndexChanged事件发生时,验证Error。
  476. /// </summary>
  477. private void CheckOnSelectedIndexChanged()
  478. {
  479. if (this._mustInput)
  480. {
  481. if (this._inputCount != this.SelectedItems.Count)
  482. {
  483. this._inputCount = this.SelectedItems.Count;
  484. if (this._inputCount > 0)
  485. {
  486. this.ClearError();
  487. }
  488. else
  489. {
  490. if (this.Items.Count > 0)
  491. {
  492. this.SetSelected(0, true);
  493. return;
  494. }
  495. this.SetError(true, ControlErrorCode.DKC_0001, this._itemName);
  496. }
  497. }
  498. }
  499. }
  500. /// <summary>
  501. /// 使父控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向父控件发送绘制消息。
  502. /// </summary>
  503. private void InvalidateBorder()
  504. {
  505. Color? borderColor = BorderColorPaint.GetBorderColor(this as IDataVerifiable, this._entered, this._mouseOver);
  506. if (borderColor != this._borderColor)
  507. {
  508. this._borderColor = borderColor;
  509. if (this.Parent == null)
  510. {
  511. this.Invalidate();
  512. }
  513. else
  514. {
  515. this.Parent.Invalidate(this.Bounds, true);
  516. }
  517. }
  518. }
  519. /*
  520. /// <summary>
  521. /// 获得边框颜色
  522. /// </summary>
  523. /// <returns>边框颜色,无时为null</returns>
  524. private Color? GetBorderColor()
  525. {
  526. if (this._errorAlert != InputErrorAlert.None &&
  527. this.HasError &&
  528. (this._errorAlert == InputErrorAlert.Always ||
  529. (this._errorAlert == InputErrorAlert.Validated && !this.Entered)))
  530. {
  531. return Constant.BORDERCOLOR_ERROR;
  532. }
  533. if (this._mustInput && this._showMustInputAlert)
  534. {
  535. return Constant.BORDERCOLOR_MUSTINPUT_EMPT;
  536. }
  537. return null;
  538. }
  539. */
  540. #endregion
  541. #region 事件处理
  542. #endregion
  543. #region IDataVerifiable 成员
  544. #region 成员变量
  545. /// <summary>
  546. /// 显示边框颜色
  547. /// </summary>
  548. private bool _showBorderColor = true;
  549. /// <summary>
  550. /// 控件的项目名
  551. /// </summary>
  552. private string _itemName = null;
  553. /// <summary>
  554. /// 控件是否是必须输入项目
  555. /// </summary>
  556. private bool _mustInput = false;
  557. /// <summary>
  558. /// 控件在验证输入错误时,如何提示
  559. /// </summary>
  560. private InputErrorAlert _errorAlert = InputErrorAlert.Validated;
  561. /// <summary>
  562. /// 是否显示必须输入项目的提示
  563. /// </summary>
  564. private bool _showMustInputAlert = true;
  565. /// <summary>
  566. /// 验证不通过时,焦点能否离开
  567. /// </summary>
  568. private bool _canLostFocusOnError = true;
  569. /// <summary>
  570. /// 验证是否有错误
  571. /// </summary>
  572. private bool _hasError = false;
  573. /// <summary>
  574. /// 是否自定义错误
  575. /// </summary>
  576. private bool _hasCustomerError = false;
  577. /// <summary>
  578. /// 错误编码
  579. /// </summary>
  580. private ControlErrorCode _errorCode = ControlErrorCode.DKC_0000;
  581. /// <summary>
  582. /// 错误消息
  583. /// </summary>
  584. private string _errorMessage = null;
  585. /// <summary>
  586. /// 自定义错误消息
  587. /// </summary>
  588. private string _customerErrorMessage = null;
  589. #endregion
  590. #region 属性
  591. /// <summary>
  592. /// 获取或设置控件是否显示边框颜色。
  593. /// </summary>
  594. [Description("获取或设置控件是否显示边框颜色。"), Category("IDataVerifiable")]
  595. [DefaultValue(true)]
  596. public bool ShowBorderColor
  597. {
  598. get
  599. {
  600. return this._showBorderColor;
  601. }
  602. set
  603. {
  604. if (this._showBorderColor != value)
  605. {
  606. this._showBorderColor = value;
  607. this.InvalidateBorder();
  608. }
  609. }
  610. }
  611. /// <summary>
  612. /// 获取或设置控件的项目名
  613. /// </summary>
  614. [Description("获取或设置控件的项目名。"), Category("IDataVerifiable")]
  615. [DefaultValue(null)]
  616. public string CDItemName
  617. {
  618. get
  619. {
  620. return this._itemName;
  621. }
  622. set
  623. {
  624. this._itemName = value;
  625. }
  626. }
  627. /// <summary>
  628. /// 获取或设置控件是否必须选中项目。
  629. /// </summary>
  630. [Description("获取或设置控件是否必须选中项目。"), Category("IDataVerifiable")]
  631. [DefaultValue(false)]
  632. public bool MustInput
  633. {
  634. get
  635. {
  636. return this._mustInput;
  637. }
  638. set
  639. {
  640. if (this._mustInput != value)
  641. {
  642. this._mustInput = value;
  643. if (value)
  644. {
  645. if (this.SelectionMode == SelectionMode.None)
  646. {
  647. this.SelectionMode = SelectionMode.One;
  648. }
  649. if (this.SelectedItems.Count == 0 &&
  650. this.Items.Count > 0)
  651. {
  652. this.SetSelected(0, true);
  653. }
  654. }
  655. this.ValidateData();
  656. if (this._mustInput && this._showMustInputAlert)
  657. {
  658. this.InvalidateBorder();
  659. }
  660. }
  661. }
  662. }
  663. /// <summary>
  664. /// 获取或设置控件是否必须选中项目。
  665. /// </summary>
  666. [Description("获取或设置控件在验证输入错误时,如何提示。"), Category("IDataVerifiable")]
  667. [DefaultValue(typeof(InputErrorAlert), "Validated")]
  668. public InputErrorAlert InputErrorAlert
  669. {
  670. get
  671. {
  672. return this._errorAlert;
  673. }
  674. set
  675. {
  676. if (this._errorAlert != value)
  677. {
  678. this._errorAlert = value;
  679. this.InvalidateBorder();
  680. }
  681. }
  682. }
  683. /// <summary>
  684. /// 获取或设置控件是否显示必须输入项目提示
  685. /// </summary>
  686. [Description("获取或设置控件是否显示必须输入项目提示。"), Category("IDataVerifiable")]
  687. [DefaultValue(true)]
  688. public bool ShowMustInputAlert
  689. {
  690. get
  691. {
  692. return this._showMustInputAlert;
  693. }
  694. set
  695. {
  696. if (this._showMustInputAlert != value)
  697. {
  698. this._showMustInputAlert = value;
  699. this.InvalidateBorder();
  700. }
  701. }
  702. }
  703. /// <summary>
  704. /// 获取或设置当验证不通过时,控件是否可以失去焦点
  705. /// </summary>
  706. [Description("获取或设置当验证不通过时,控件是否可以失去焦点。"), Category("IDataVerifiable")]
  707. [DefaultValue(true)]
  708. public bool CanLostFocusOnError
  709. {
  710. get
  711. {
  712. return this._canLostFocusOnError;
  713. }
  714. set
  715. {
  716. this._canLostFocusOnError = value;
  717. }
  718. }
  719. /// <summary>
  720. /// 获取控件校验时是否有错误
  721. /// </summary>
  722. [Description("获取控件校验时是否有错误。"), Category("IDataVerifiable")]
  723. [DefaultValue(false)]
  724. public bool HasError
  725. {
  726. get
  727. {
  728. return this._hasCustomerError || this._hasError;
  729. }
  730. }
  731. /// <summary>
  732. /// 获取控件校验时的错误编码
  733. /// </summary>
  734. [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")]
  735. [DefaultValue(typeof(ControlErrorCode), "DKC_0000")]
  736. public ControlErrorCode ErrorCode
  737. {
  738. get
  739. {
  740. return this._hasCustomerError ? ControlErrorCode.DKC_C001 : this._errorCode;
  741. }
  742. }
  743. /// <summary>
  744. /// 获取控件校验时的错误消息
  745. /// </summary>
  746. [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")]
  747. [DefaultValue(null)]
  748. public string ErrorMessage
  749. {
  750. get
  751. {
  752. return this._hasCustomerError ? this._customerErrorMessage : this._errorMessage;
  753. }
  754. }
  755. #endregion
  756. #region 公有方法
  757. /// <summary>
  758. /// 设置自定义错误
  759. /// </summary>
  760. /// <param name="hasError">输入是否有错误</param>
  761. /// <param name="errorMessage">错误消息</param>
  762. public virtual void SetCustomerError(bool hasError, string errorMessage)
  763. {
  764. if (this._hasCustomerError != hasError ||
  765. this._customerErrorMessage != errorMessage)
  766. {
  767. this._hasCustomerError = hasError;
  768. this._customerErrorMessage = errorMessage;
  769. this.OnHasErrorChanged(EventArgs.Empty);
  770. this.InvalidateBorder();
  771. }
  772. }
  773. /// <summary>
  774. /// 清除自定义错误
  775. /// </summary>
  776. public virtual void ClearCustomerError()
  777. {
  778. this.SetCustomerError(false, null);
  779. }
  780. /// <summary>
  781. /// 验证输入内容
  782. /// </summary>
  783. /// <returns>验证结果</returns>
  784. public virtual bool ValidateData()
  785. {
  786. if (this._mustInput && this.SelectedItems.Count == 0)
  787. {
  788. this.SetError(true, ControlErrorCode.DKC_0001, this._itemName);
  789. return false;
  790. }
  791. this.ClearError();
  792. return true;
  793. }
  794. /// <summary>
  795. /// 清除输入项
  796. /// </summary>
  797. public virtual void ClearValue()
  798. {
  799. this.ClearSelected();
  800. }
  801. #endregion
  802. #region 保护方法
  803. /// <summary>
  804. /// 设置验证不通过错误
  805. /// </summary>
  806. /// <param name="hasError">是否有错误</param>
  807. /// <param name="code">错误编码</param>
  808. /// <param name="args">设置格式的对象</param>
  809. protected void SetError(bool hasError, ControlErrorCode code, params object[] args)
  810. {
  811. if (this._hasError != hasError ||
  812. this._errorCode != code)
  813. {
  814. this._hasError = hasError;
  815. this._errorCode = code;
  816. if (args != null && args.Length > 0)
  817. {
  818. this._errorMessage = string.Format(code.GetDescription(), args);
  819. }
  820. else
  821. {
  822. this._errorMessage = code.GetDescription();
  823. }
  824. this.OnHasErrorChanged(EventArgs.Empty);
  825. this.InvalidateBorder();
  826. }
  827. }
  828. /// <summary>
  829. /// 清除验证不通过错误
  830. /// </summary>
  831. protected void ClearError()
  832. {
  833. this.SetError(false, ControlErrorCode.DKC_0000);
  834. }
  835. #endregion
  836. #endregion
  837. #region IAsyncControl 成员
  838. #region 成员变量
  839. /// <summary>
  840. /// 异步处理开始时,控件状态
  841. /// </summary>
  842. private bool _asyncBeginStatus = false;
  843. private bool _asyncBeginFocused = false;
  844. #endregion
  845. #region 公有方法
  846. /// <summary>
  847. /// 开始异步处理
  848. /// </summary>
  849. /// <param name="doFocus">是否处理焦点</param>
  850. public virtual void BeginAsync(ref bool doFocus)
  851. {
  852. this._asyncBeginFocused = false;
  853. if (doFocus && this.Focused)
  854. {
  855. this._asyncBeginFocused = true;
  856. doFocus = false;
  857. }
  858. this._asyncBeginStatus = this.Enabled;
  859. this.Enabled = false;
  860. }
  861. /// <summary>
  862. /// 结束异步处理
  863. /// </summary>
  864. public virtual void EndAsync()
  865. {
  866. this.Enabled = this._asyncBeginStatus;
  867. if (this._asyncBeginFocused)
  868. {
  869. this.Focus();
  870. }
  871. }
  872. #endregion
  873. #endregion
  874. }
  875. }