TextBoxEx.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Documents;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using System.Windows.Navigation;
  15. using System.Windows.Shapes;
  16. namespace OpenSEMI.Ctrlib.Controls
  17. {
  18. public enum EditBoxMode
  19. {
  20. Default,
  21. SignInteger,
  22. UnSignInteger,
  23. Decimal,
  24. UnSignDecimal,
  25. Email,
  26. Time,
  27. FileName
  28. }
  29. public class TextBoxEx : TextBox
  30. {
  31. public event KeyEventHandler TextBoxExEnterKeyDown;
  32. #region define fields & properties
  33. private string m_strOldValue = string.Empty;
  34. public EditBoxMode EditBoxMode
  35. {
  36. get { return (EditBoxMode)GetValue(EditBoxModeProperty); }
  37. set { SetValue(EditBoxModeProperty, value); }
  38. }
  39. public static readonly DependencyProperty EditBoxModeProperty = DependencyProperty.Register("EditBoxMode", typeof(EditBoxMode), typeof(TextBoxEx), new UIPropertyMetadata(EditBoxMode.Default));
  40. #region NormalColor (DependencyProperty)
  41. public static readonly DependencyProperty NormalColorProperty = DependencyProperty.Register("NormalColor", typeof(Brush), typeof(TextBoxEx));
  42. public Brush NormalColor
  43. {
  44. get { return (Brush)GetValue(NormalColorProperty); }
  45. set { SetValue(NormalColorProperty, value); }
  46. }
  47. #endregion
  48. #region ChangedColor (DependencyProperty)
  49. public static readonly DependencyProperty ChangedColorProperty = DependencyProperty.Register("ChangedColor", typeof(Brush), typeof(TextBoxEx));
  50. public Brush ChangedColor
  51. {
  52. get { return (Brush)GetValue(ChangedColorProperty); }
  53. set { SetValue(ChangedColorProperty, value); }
  54. }
  55. #endregion
  56. #region WarningColor (DependencyProperty)
  57. public static readonly DependencyProperty WarningColorProperty = DependencyProperty.Register("WarningColor", typeof(Brush), typeof(TextBoxEx));
  58. public Brush WarningColor
  59. {
  60. get { return (Brush)GetValue(WarningColorProperty); }
  61. set { SetValue(WarningColorProperty, value); }
  62. }
  63. #endregion
  64. private bool m_AllowEmpty = true;
  65. public bool AllowEmpty
  66. {
  67. get { return m_AllowEmpty; }
  68. set { m_AllowEmpty = value; }
  69. }
  70. /// <summary>
  71. /// This is a flag to indicate that whether to change the bg color
  72. /// when the text changed by backgroud not by GUI side.
  73. /// This flag is true when control is bound to display text from dialog
  74. /// </summary>
  75. private bool m_AllowBackgroundChange = true;
  76. public bool AllowBackgroundChange
  77. {
  78. get { return m_AllowBackgroundChange; }
  79. set { m_AllowBackgroundChange = value; }
  80. }
  81. private bool m_AllowIsOutOfRangeSaveChange = true;
  82. public bool AllowIsOutOfRangeSaveChange
  83. {
  84. get { return m_AllowIsOutOfRangeSaveChange; }
  85. set { m_AllowIsOutOfRangeSaveChange = value; }
  86. }
  87. private int m_KeepDecimals = -1;
  88. public int KeepDecimals
  89. {
  90. get { return m_KeepDecimals; }
  91. set { m_KeepDecimals = value; }
  92. }
  93. private int m_KeepIntegers = -1;
  94. public int KeepIntegers
  95. {
  96. get { return m_KeepIntegers; }
  97. set { m_KeepIntegers = value; }
  98. }
  99. public bool IsZeroNoChangedColor
  100. {
  101. get { return (bool)GetValue(IsZeroNoChangedColorProperty); }
  102. set { SetValue(IsZeroNoChangedColorProperty, value); }
  103. }
  104. public static readonly DependencyProperty IsZeroNoChangedColorProperty =
  105. DependencyProperty.Register("IsZeroNoChangedColorProperty", typeof(bool), typeof(TextBoxEx), new PropertyMetadata(false));
  106. public override void OnApplyTemplate()
  107. {
  108. base.OnApplyTemplate();
  109. //this.TextSaved = true;
  110. }
  111. #region MaxValue (DependencyProperty)
  112. public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(TextBoxEx), new FrameworkPropertyMetadata(double.NaN) { BindsTwoWayByDefault = true });
  113. public double MaxValue
  114. {
  115. get { return (double)GetValue(MaxValueProperty); }
  116. set { SetValue(MaxValueProperty, value); }
  117. }
  118. #endregion
  119. #region MinValue (DependencyProperty)
  120. public double MinValue
  121. {
  122. get { return (double)GetValue(MinValueProperty); }
  123. set { SetValue(MinValueProperty, value); }
  124. }
  125. public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(TextBoxEx), new UIPropertyMetadata(double.NaN));
  126. #endregion
  127. #region Accuracy (DependencyProperty)
  128. public Int32 Accuracy
  129. {
  130. get { return (Int32)GetValue(AccuracyProperty); }
  131. set { SetValue(AccuracyProperty, value); }
  132. }
  133. public static readonly DependencyProperty AccuracyProperty = DependencyProperty.Register("Accuracy", typeof(Int32), typeof(TextBoxEx), new UIPropertyMetadata(4));
  134. #endregion
  135. #region TextSaved (DependencyProperty)
  136. public bool TextSaved
  137. {
  138. get { return (bool)GetValue(TextSavedProperty); }
  139. set { SetValue(TextSavedProperty, value); }
  140. }
  141. public static readonly DependencyProperty TextSavedProperty =
  142. DependencyProperty.Register("TextSaved", typeof(bool), typeof(TextBoxEx),
  143. new UIPropertyMetadata(true, new PropertyChangedCallback(TextSavedChangedCallBack)));
  144. #endregion
  145. #region IsScrollToEnd (DependencyProperty)
  146. public Boolean IsScrollToEnd
  147. {
  148. get { return (Boolean)GetValue(ScrollToEndProperty); }
  149. set { SetValue(ScrollToEndProperty, value); }
  150. }
  151. public static readonly DependencyProperty ScrollToEndProperty = DependencyProperty.Register("IsScrollToEnd", typeof(Boolean), typeof(TextBoxEx), new UIPropertyMetadata(false));
  152. #endregion
  153. public Boolean IsTextboxFocused
  154. {
  155. get { return (Boolean)GetValue(IsTextboxFocusedProperty); }
  156. set { SetValue(IsTextboxFocusedProperty, value); }
  157. }
  158. public static readonly DependencyProperty IsTextboxFocusedProperty = DependencyProperty.Register("IsTextboxFocused", typeof(Boolean), typeof(TextBoxEx), new UIPropertyMetadata(false));
  159. #endregion
  160. static TextBoxEx()
  161. {
  162. DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBoxEx), new FrameworkPropertyMetadata(typeof(TextBoxEx)));
  163. }
  164. #region Input Control
  165. protected override void OnPreviewKeyDown(KeyEventArgs e)
  166. {
  167. switch (this.EditBoxMode)
  168. {
  169. case EditBoxMode.SignInteger:
  170. AllowInteger(e);
  171. break;
  172. case EditBoxMode.UnSignInteger:
  173. AllowUnsignInteger(e);
  174. break;
  175. case EditBoxMode.Decimal:
  176. AllowDecimal(e);
  177. break;
  178. case EditBoxMode.UnSignDecimal:
  179. AllowUnSignDecimal(e);
  180. break;
  181. case EditBoxMode.Time:
  182. AllowTime(e);
  183. break;
  184. case EditBoxMode.FileName:
  185. AllowFileName(e);
  186. break;
  187. }
  188. }
  189. private void AllowInteger(KeyEventArgs e)
  190. {
  191. bool isControl = ((Keyboard.Modifiers != ModifierKeys.None && Keyboard.Modifiers != ModifierKeys.Shift)
  192. || e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Insert
  193. || e.Key == Key.Down || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up
  194. || e.Key == Key.Tab
  195. || e.Key == Key.PageDown || e.Key == Key.PageUp
  196. || e.Key == Key.Enter || e.Key == Key.Return || e.Key == Key.Escape
  197. || e.Key == Key.Home || e.Key == Key.End);
  198. //if (this.Text.IndexOfAny(new char[] { '-' }, 0) > -1 && this.CaretIndex == 0 && !isControl) //Disable input before minus
  199. //{
  200. // e.Handled = true;
  201. // return;
  202. //}
  203. bool isNumPadNumeric = (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9);
  204. bool isNumeric = (e.Key >= Key.D0 && e.Key <= Key.D9);
  205. if ((isNumeric || isNumPadNumeric) && Keyboard.Modifiers != ModifierKeys.None)
  206. {
  207. e.Handled = true;
  208. return;
  209. }
  210. //Minus
  211. if (e.Key == Key.OemMinus || e.Key == Key.Subtract)
  212. {
  213. if (Keyboard.Modifiers == ModifierKeys.Shift)
  214. {
  215. isControl = false;
  216. }
  217. else
  218. {
  219. if (this.Text.IndexOfAny(new char[] { '-' }, 0) == -1 && this.CaretIndex == 0)
  220. {
  221. isControl = true;
  222. }
  223. else
  224. {
  225. e.Handled = true;
  226. return;
  227. }
  228. }
  229. }
  230. e.Handled = !isControl && !isNumeric && !isNumPadNumeric;
  231. }
  232. private void AllowUnsignInteger(KeyEventArgs e)
  233. {
  234. bool isNumPadNumeric = (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9);
  235. bool isNumeric = (e.Key >= Key.D0 && e.Key <= Key.D9);
  236. if ((isNumeric || isNumPadNumeric) && Keyboard.Modifiers != ModifierKeys.None)
  237. {
  238. e.Handled = true;
  239. return;
  240. }
  241. bool isControl = ((Keyboard.Modifiers != ModifierKeys.None && Keyboard.Modifiers != ModifierKeys.Shift)
  242. || e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Insert
  243. || e.Key == Key.Down || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up
  244. || e.Key == Key.Tab
  245. || e.Key == Key.PageDown || e.Key == Key.PageUp
  246. || e.Key == Key.Enter || e.Key == Key.Return || e.Key == Key.Escape
  247. || e.Key == Key.Home || e.Key == Key.End);
  248. e.Handled = !isControl && !isNumeric && !isNumPadNumeric;
  249. }
  250. private void AllowDecimal(KeyEventArgs e)
  251. {
  252. bool isControl = ((Keyboard.Modifiers != ModifierKeys.None && Keyboard.Modifiers != ModifierKeys.Shift)
  253. || e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Insert
  254. || e.Key == Key.Down || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up
  255. || e.Key == Key.Tab
  256. || e.Key == Key.PageDown || e.Key == Key.PageUp
  257. || e.Key == Key.Enter || e.Key == Key.Return || e.Key == Key.Escape
  258. || e.Key == Key.Home || e.Key == Key.End);
  259. //if (this.Text.IndexOfAny(new char[] { '-' }, 0) > -1 && this.CaretIndex == 0 && !isControl) //Disable input before minus
  260. //{
  261. // e.Handled = true;
  262. // return;
  263. //}
  264. bool isNumPadNumeric = (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9);
  265. bool isNumeric = (e.Key >= Key.D0 && e.Key <= Key.D9);
  266. if ((isNumeric || isNumPadNumeric) && Keyboard.Modifiers != ModifierKeys.None)
  267. {
  268. e.Handled = true;
  269. return;
  270. }
  271. //Minus
  272. if (e.Key == Key.OemMinus || e.Key == Key.Subtract)
  273. {
  274. if (Keyboard.Modifiers == ModifierKeys.Shift)
  275. {
  276. isControl = false;
  277. }
  278. else
  279. {
  280. if (this.Text.IndexOfAny(new char[] { '-' }, 0) == -1 && this.CaretIndex == 0)
  281. {
  282. isControl = true;
  283. }
  284. else
  285. {
  286. e.Handled = true;
  287. return;
  288. }
  289. }
  290. }
  291. //Decimal point
  292. if (e.Key == Key.OemPeriod || e.Key == Key.Decimal)
  293. {
  294. if (Keyboard.Modifiers == ModifierKeys.Shift)
  295. {
  296. isControl = false;
  297. }
  298. else
  299. {
  300. if (this.Text.IndexOfAny(new char[] { '.' }, 0) == -1 && this.CaretIndex > 0
  301. && this.CaretIndex + this.Accuracy >= this.Text.Length) //Accuracy
  302. {
  303. isControl = true;
  304. }
  305. else
  306. {
  307. e.Handled = true;
  308. return;
  309. }
  310. }
  311. }
  312. //Accuracy
  313. int pointIndex = this.Text.IndexOf('.');
  314. if (pointIndex > -1 && this.CaretIndex > pointIndex)
  315. {
  316. if (this.Text.Length - pointIndex > this.Accuracy)
  317. {
  318. isNumeric = isNumPadNumeric = false;
  319. }
  320. }
  321. e.Handled = !isControl && !isNumeric && !isNumPadNumeric;
  322. }
  323. private void AllowUnSignDecimal(KeyEventArgs e)
  324. {
  325. bool isNumPadNumeric = (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9);
  326. bool isNumeric = (e.Key >= Key.D0 && e.Key <= Key.D9);
  327. if ((isNumeric || isNumPadNumeric) && Keyboard.Modifiers != ModifierKeys.None)
  328. {
  329. e.Handled = true;
  330. return;
  331. }
  332. bool isControl = ((Keyboard.Modifiers != ModifierKeys.None && Keyboard.Modifiers != ModifierKeys.Shift)
  333. || e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Insert
  334. || e.Key == Key.Down || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up
  335. || e.Key == Key.Tab
  336. || e.Key == Key.PageDown || e.Key == Key.PageUp
  337. || e.Key == Key.Enter || e.Key == Key.Return || e.Key == Key.Escape
  338. || e.Key == Key.Home || e.Key == Key.End);
  339. //Decimal point
  340. if (e.Key == Key.OemPeriod || e.Key == Key.Decimal)
  341. {
  342. if (Keyboard.Modifiers == ModifierKeys.Shift)
  343. {
  344. isControl = false;
  345. }
  346. else
  347. {
  348. if (this.Text.IndexOfAny(new char[] { '.' }, 0) == -1 && this.CaretIndex > 0
  349. && this.CaretIndex + this.Accuracy >= this.Text.Length) //Accuracy
  350. {
  351. isControl = true;
  352. }
  353. else
  354. {
  355. e.Handled = true;
  356. return;
  357. }
  358. }
  359. }
  360. //Accuracy
  361. int pointIndex = this.Text.IndexOf('.');
  362. if (pointIndex > -1 && this.CaretIndex > pointIndex)
  363. {
  364. if (this.Text.Length - pointIndex > this.Accuracy)
  365. {
  366. isNumeric = isNumPadNumeric = false;
  367. }
  368. }
  369. e.Handled = !isControl && !isNumeric && !isNumPadNumeric;
  370. }
  371. private void AllowTime(KeyEventArgs e)
  372. {
  373. AllowDecimal(e);
  374. if (e.Key == Key.Oem1 && Keyboard.Modifiers == ModifierKeys.Shift)
  375. e.Handled = false;
  376. if (e.Key == Key.OemMinus || e.Key == Key.Subtract)
  377. e.Handled = true;
  378. }
  379. private void AllowFileName(KeyEventArgs e)
  380. {
  381. if (this.Text.Length >= 128)
  382. {
  383. e.Handled = true;
  384. return;
  385. }
  386. if (Keyboard.Modifiers == ModifierKeys.Shift)
  387. {
  388. if (e.Key == Key.OemPeriod || //>
  389. e.Key == Key.OemComma || //<
  390. e.Key == Key.D8 || //*
  391. e.Key == Key.Oem1 || //:
  392. e.Key == Key.Oem7 //"
  393. )
  394. {
  395. e.Handled = true;
  396. return;
  397. }
  398. }
  399. if (e.Key == Key.Oem2 || //? /
  400. e.Key == Key.Oem5) //\ |
  401. {
  402. e.Handled = true;
  403. return;
  404. }
  405. }
  406. #endregion
  407. #region Range Control
  408. public bool IsOutOfRange()
  409. {
  410. if (!double.IsNaN(this.MinValue) && !double.IsNaN(this.MaxValue))
  411. {
  412. double value;
  413. bool m_flag = double.TryParse(this.Text, out value);
  414. if (value > this.MaxValue)
  415. return true;
  416. else if (value < this.MinValue)
  417. return true;
  418. else
  419. return false;
  420. }
  421. return false;
  422. }
  423. public bool IsOutOfRange(double value)
  424. {
  425. if (!double.IsNaN(this.MinValue) && !double.IsNaN(this.MaxValue))
  426. {
  427. if (value > this.MaxValue)
  428. return true;
  429. else if (value < this.MinValue)
  430. return true;
  431. else
  432. return false;
  433. }
  434. return false;
  435. }
  436. protected override void OnLostFocus(RoutedEventArgs e)
  437. {
  438. base.OnLostFocus(e);
  439. this.IsTextboxFocused = false;
  440. if (this.Text.Length == 0)
  441. {
  442. if (!AllowEmpty)
  443. this.Text = m_strOldValue;
  444. return;
  445. }
  446. else
  447. {
  448. if (EditBoxMode == EditBoxMode.UnSignDecimal || EditBoxMode == EditBoxMode.Decimal || EditBoxMode == EditBoxMode.SignInteger || EditBoxMode == EditBoxMode.UnSignInteger)
  449. {
  450. if (IsOutOfRange())
  451. {
  452. this.Background = Brushes.Red;
  453. this.ToolTip = this.MinValue + "-" + this.MaxValue;
  454. }
  455. else
  456. {
  457. SetBGColor(this);
  458. }
  459. }
  460. }
  461. }
  462. #endregion
  463. #region Expose an event to support save function by ENTER key
  464. protected override void OnKeyDown(KeyEventArgs e)
  465. {
  466. if (e.Key == Key.Tab)
  467. {
  468. this.SelectAll();
  469. }
  470. KeyEventHandler handler = this.TextBoxExEnterKeyDown;
  471. if (handler != null && e.Key == Key.Enter)
  472. {
  473. if (IsOutOfRange())
  474. {
  475. this.Background = Brushes.Red; //this.WarningColor
  476. this.ToolTip = this.MinValue + "-" + this.MaxValue;
  477. }
  478. else
  479. handler(this, e);
  480. }
  481. if (e.Key == Key.Return || e.Key == Key.Enter)
  482. {
  483. if (IsOutOfRange())
  484. {
  485. this.Background = Brushes.Red;
  486. this.ToolTip = this.MinValue + "-" + this.MaxValue;
  487. }
  488. else
  489. {
  490. SetBGColor(this);
  491. }
  492. }
  493. }
  494. #endregion
  495. protected override void OnTextChanged(TextChangedEventArgs e)
  496. {
  497. base.OnTextChanged(e);
  498. if (IsInitialized)
  499. {
  500. //text changed because of binding changed
  501. if (m_strOldValue != this.Text && AllowBackgroundChange)// && this.IsFocused
  502. {
  503. //this.TextSaved = false;
  504. }
  505. else
  506. {
  507. this.m_strOldValue = this.Text;
  508. // this.TextSaved = true;
  509. }
  510. if (EditBoxMode == EditBoxMode.Default)
  511. {
  512. this.m_strOldValue = this.Text;
  513. }
  514. else if (EditBoxMode == EditBoxMode.FileName)
  515. {
  516. Regex regex = new Regex("\\*|\\\\|\\/|\\?|\"|:|\\<|\\>|\\|"); //*:"<>?/\|
  517. this.Text = regex.Replace(this.Text, String.Empty);
  518. }
  519. else
  520. {
  521. double.TryParse(this.Text, out double controlValue);
  522. if (IsOutOfRange(controlValue))
  523. {
  524. this.Background = Brushes.Red; //this.WarningColor
  525. this.ToolTip = this.MinValue + "-" + this.MaxValue;
  526. }
  527. else
  528. {
  529. SetBGColor(this);
  530. this.ToolTip = this.MinValue + "-" + this.MaxValue;
  531. }
  532. if (KeepDecimals != -1)
  533. {
  534. if (KeepIntegers != -1)
  535. {
  536. StringBuilder strFormat = new StringBuilder();
  537. for (int i = 0; i < KeepIntegers; i++)
  538. {
  539. strFormat.Append("0");
  540. }
  541. strFormat.Append(".");
  542. for (int i = 0; i < KeepDecimals; i++)
  543. {
  544. strFormat.Append("0");
  545. }
  546. Text = controlValue.ToString(strFormat.ToString());
  547. }
  548. else
  549. { Text = controlValue.ToString($"f{KeepDecimals}"); }
  550. }
  551. else
  552. {
  553. if (KeepIntegers != -1)
  554. {
  555. Text = ((int)controlValue).ToString($"D{KeepIntegers}");
  556. }
  557. else
  558. { Text = controlValue.ToString(); }
  559. }
  560. }
  561. }
  562. if (IsScrollToEnd)
  563. {
  564. this.ScrollToEnd();
  565. }
  566. }
  567. protected override void OnMouseDown(MouseButtonEventArgs e)
  568. {
  569. base.OnMouseDown(e);
  570. if (e.ClickCount == 2)
  571. {
  572. this.SelectAll();
  573. }
  574. }
  575. protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
  576. {
  577. base.OnGotKeyboardFocus(e);
  578. this.IsTextboxFocused = true;
  579. }
  580. private static void TextSavedChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs args)
  581. {
  582. TextBoxEx m_txt = d as TextBoxEx;
  583. if (m_txt != null)
  584. {
  585. if (m_txt.IsOutOfRange())
  586. {
  587. m_txt.Background = Brushes.Red;
  588. m_txt.ToolTip = m_txt.MinValue + "-" + m_txt.MaxValue;
  589. }
  590. else
  591. {
  592. SetBGColor(m_txt);
  593. }
  594. }
  595. }
  596. /// <summary>
  597. /// Set the Background of textbox according to the TextSaved property
  598. /// </summary>
  599. private static void SetBGColor(TextBoxEx tb)
  600. {
  601. if (tb.TextSaved)
  602. {
  603. tb.m_strOldValue = tb.Text;
  604. if (tb.NormalColor != null)
  605. tb.Background = tb.NormalColor;
  606. }
  607. else
  608. {
  609. if (tb.ChangedColor != null)
  610. {
  611. if (tb.IsZeroNoChangedColor)
  612. {
  613. double.TryParse(tb.Text, out double value);
  614. if (Math.Abs(value) < 0.000001)
  615. {
  616. tb.Background = tb.NormalColor;
  617. }
  618. else
  619. {
  620. tb.Background = tb.ChangedColor;
  621. }
  622. }
  623. else
  624. {
  625. tb.Background = tb.ChangedColor;
  626. }
  627. }
  628. else
  629. {
  630. tb.Background = tb.ChangedColor;
  631. }
  632. }
  633. }
  634. protected override void OnMouseEnter(MouseEventArgs e)
  635. {
  636. base.OnMouseEnter(e);
  637. this.Focus();
  638. }
  639. protected override void OnMouseLeave(MouseEventArgs e)
  640. {
  641. base.OnMouseLeave(e);
  642. }
  643. public void SaveText()
  644. {
  645. this.TextSaved = true;
  646. }
  647. }
  648. }