TextBoxRejected.cs 40 KB

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