终端一体化运控平台
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NumberBox.cs 12 KiB

2 년 전
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. using BPASmartClient.Compiler;
  2. using BPASmartClient.SCADAControl;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Documents;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. using System.Windows.Navigation;
  16. using System.Windows.Shapes;
  17. namespace BPASmartClient.SCADAControl.CustomerControls
  18. {
  19. public class NumberBox : TextBox, IExecutable
  20. {
  21. public event EventHandler PropertyChange; //声明一个事件
  22. static NumberBox()
  23. {
  24. DefaultStyleKeyProperty.OverrideMetadata(typeof(NumberBox), new FrameworkPropertyMetadata(typeof(NumberBox)));
  25. FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(CURVALUE, new PropertyChangedCallback(OnCurValueChanged));
  26. CurValueProperty = DependencyProperty.Register("CurValue", typeof(double), typeof(NumberBox), metadata);
  27. metadata = new FrameworkPropertyMetadata(MINVALUE, new PropertyChangedCallback(OnMinValueChanged));
  28. MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(NumberBox), metadata);
  29. metadata = new FrameworkPropertyMetadata(MAXVALUE, new PropertyChangedCallback(OnMaxValueChanged));
  30. MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(NumberBox), metadata);
  31. metadata = new FrameworkPropertyMetadata(DIGITS, new PropertyChangedCallback(OnDigitsChanged));
  32. DigitsProperty = DependencyProperty.Register("Digits", typeof(int), typeof(NumberBox), metadata);
  33. }
  34. public string ControlType => "控件";
  35. public NumberBox()
  36. {
  37. Width = 80;
  38. Height = 30;
  39. CurValue = 0.01;
  40. Digits = 2;
  41. FontSize = 16;
  42. VerticalContentAlignment = VerticalAlignment.Center;
  43. ResourceDictionary languageResDic = new ResourceDictionary();
  44. languageResDic.Source = new Uri(@"/BPASmartClient.SCADAControl;component/Themes/Generic.xaml",UriKind.RelativeOrAbsolute);
  45. this.Resources.MergedDictionaries.Add(languageResDic);
  46. //Style = Application.Current.Resources["DesignNumberBox"] as Style;//FindResource("DesignNumberBox") as Style;
  47. this.TextChanged += NumberBox_TextChanged;
  48. this.PreviewKeyDown += NumberBox_KeyDown;
  49. this.LostFocus += NumberBox_LostFocus;
  50. DataObject.AddPastingHandler(this, NumberBox_Pasting);
  51. Focusable = false;
  52. }
  53. private bool isExecuteState;
  54. public bool IsExecuteState
  55. {
  56. get { return isExecuteState; }
  57. set
  58. {
  59. isExecuteState = value;
  60. if (IsExecuteState)
  61. {
  62. IsEnabled = true;
  63. Register();
  64. //Style = null;
  65. Focusable = true;
  66. }
  67. }
  68. }
  69. public void Register()
  70. {
  71. }
  72. #region DependencyProperty
  73. private const double CURVALUE = 0; //当前值
  74. private const double MINVALUE = double.MinValue; //最小值
  75. private const double MAXVALUE = double.MaxValue; //最大值
  76. private const int DIGITS = 15; //小数点精度
  77. public static readonly DependencyProperty CurValueProperty;
  78. public static readonly DependencyProperty MinValueProperty;
  79. public static readonly DependencyProperty MaxValueProperty;
  80. public static readonly DependencyProperty DigitsProperty;
  81. public double CurValue
  82. {
  83. get
  84. {
  85. return (double)GetValue(CurValueProperty);
  86. }
  87. set
  88. {
  89. double v = value;
  90. if (value < MinValue)
  91. {
  92. v = MinValue;
  93. }
  94. else if (value > MaxValue)
  95. {
  96. v = MaxValue;
  97. }
  98. v = Math.Round(v, Digits);
  99. SetValue(CurValueProperty, v);
  100. // if do not go into OnCurValueChanged then force update ui
  101. if (v != value)
  102. {
  103. this.Text = v.ToString();
  104. }
  105. }
  106. }
  107. public double MinValue
  108. {
  109. get
  110. {
  111. return (double)GetValue(MinValueProperty);
  112. }
  113. set
  114. {
  115. SetValue(MinValueProperty, value);
  116. }
  117. }
  118. public double MaxValue
  119. {
  120. get
  121. {
  122. return (double)GetValue(MaxValueProperty);
  123. }
  124. set
  125. {
  126. SetValue(MaxValueProperty, value);
  127. }
  128. }
  129. public int Digits
  130. {
  131. get
  132. {
  133. return (int)GetValue(DigitsProperty);
  134. }
  135. set
  136. {
  137. int digits = value;
  138. if (digits <= 0)
  139. {
  140. digits = 0;
  141. }
  142. if (digits > 15)
  143. {
  144. digits = 15;
  145. }
  146. SetValue(DigitsProperty, value);
  147. }
  148. }
  149. private static void OnCurValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
  150. {
  151. double value = (double)e.NewValue;
  152. NumberBox numericBox = (NumberBox)sender;
  153. numericBox.Text = value.ToString();
  154. }
  155. private static void OnMinValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
  156. {
  157. double minValue = (double)e.NewValue;
  158. NumberBox numericBox = (NumberBox)sender;
  159. numericBox.MinValue = minValue;
  160. }
  161. private static void OnMaxValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
  162. {
  163. double maxValue = (double)e.NewValue;
  164. NumberBox numericBox = (NumberBox)sender;
  165. numericBox.MaxValue = maxValue;
  166. }
  167. private static void OnDigitsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
  168. {
  169. int digits = (int)e.NewValue;
  170. NumberBox numericBox = (NumberBox)sender;
  171. numericBox.CurValue = Math.Round(numericBox.CurValue, digits);
  172. numericBox.MinValue = Math.Round(numericBox.MinValue, digits);
  173. numericBox.MaxValue = Math.Round(numericBox.MaxValue, digits);
  174. }
  175. #endregion
  176. void NumberBox_TextChanged(object sender, TextChangedEventArgs e)
  177. {
  178. NumberBox numericBox = sender as NumberBox;
  179. if (string.IsNullOrEmpty(numericBox.Text))
  180. {
  181. return;
  182. }
  183. TrimZeroStart();
  184. double value = MinValue;
  185. if (!Double.TryParse(numericBox.Text, out value))
  186. {
  187. return;
  188. }
  189. if (value != this.CurValue)
  190. {
  191. this.CurValue = value;
  192. }
  193. }
  194. void NumberBox_KeyDown(object sender, KeyEventArgs e)
  195. {
  196. Key key = e.Key;
  197. if (IsControlKeys(key))
  198. {
  199. return;
  200. }
  201. else if (IsDigit(key))
  202. {
  203. return;
  204. }
  205. else if (IsSubtract(key)) //-
  206. {
  207. TextBox textBox = sender as TextBox;
  208. string str = textBox.Text;
  209. if (str.Length > 0 && textBox.SelectionStart != 0)
  210. {
  211. e.Handled = true;
  212. }
  213. }
  214. else if (IsDot(key)) //point
  215. {
  216. if (this.Digits > 0)
  217. {
  218. TextBox textBox = sender as TextBox;
  219. string str = textBox.Text;
  220. if (str.Contains('.') || str == "-")
  221. {
  222. e.Handled = true;
  223. }
  224. }
  225. else
  226. {
  227. e.Handled = true;
  228. }
  229. }
  230. else
  231. {
  232. e.Handled = true;
  233. }
  234. }
  235. void NumberBox_LostFocus(object sender, RoutedEventArgs e)
  236. {
  237. NumberBox numericBox = sender as NumberBox;
  238. if (string.IsNullOrEmpty(numericBox.Text))
  239. {
  240. numericBox.Text = this.CurValue.ToString();
  241. }
  242. }
  243. private void NumberBox_Pasting(object sender, DataObjectPastingEventArgs e)
  244. {
  245. e.CancelCommand();
  246. }
  247. private static readonly List<Key> _controlKeys = new List<Key>
  248. {
  249. Key.Back,
  250. Key.CapsLock,
  251. Key.Down,
  252. Key.End,
  253. Key.Enter,
  254. Key.Escape,
  255. Key.Home,
  256. Key.Insert,
  257. Key.Left,
  258. Key.PageDown,
  259. Key.PageUp,
  260. Key.Right,
  261. Key.Tab,
  262. Key.Up
  263. };
  264. public static bool IsControlKeys(Key key)
  265. {
  266. return _controlKeys.Contains(key);
  267. }
  268. public static bool IsDigit(Key key)
  269. {
  270. bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;
  271. bool retVal;
  272. if (key >= Key.D0 && key <= Key.D9 && !shiftKey)
  273. {
  274. retVal = true;
  275. }
  276. else
  277. {
  278. retVal = key >= Key.NumPad0 && key <= Key.NumPad9;
  279. }
  280. return retVal;
  281. }
  282. public static bool IsDot(Key key)
  283. {
  284. bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;
  285. bool flag = false;
  286. if (key == Key.Decimal)
  287. {
  288. flag = true;
  289. }
  290. if (key == Key.OemPeriod && !shiftKey)
  291. {
  292. flag = true;
  293. }
  294. return flag;
  295. }
  296. public static bool IsSubtract(Key key)
  297. {
  298. bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;
  299. bool flag = false;
  300. if (key == Key.Subtract)
  301. {
  302. flag = true;
  303. }
  304. if (key == Key.OemMinus && !shiftKey)
  305. {
  306. flag = true;
  307. }
  308. return flag;
  309. }
  310. private void TrimZeroStart()
  311. {
  312. if (this.Text.Length == 1)
  313. {
  314. return;
  315. }
  316. string resultText = this.Text;
  317. int zeroCount = 0;
  318. foreach (char c in this.Text)
  319. {
  320. if (c == '0') { zeroCount++; }
  321. else { break; }
  322. }
  323. if (zeroCount == 0)
  324. {
  325. return;
  326. }
  327. if (this.Text.Contains('.'))
  328. {
  329. if (this.Text[zeroCount] != '.')
  330. {
  331. resultText = this.Text.TrimStart('0');
  332. }
  333. else if (zeroCount > 1)
  334. {
  335. resultText = this.Text.Substring(zeroCount - 1);
  336. }
  337. }
  338. else if (zeroCount > 0)
  339. {
  340. resultText = this.Text.TrimStart('0');
  341. }
  342. }
  343. }
  344. }