终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

373 lines
12 KiB

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