using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace OpenSEMI.Ctrlib.Controls { public class TextBoxEx : TextBox { private string m_strOldValue = string.Empty; public static readonly DependencyProperty EditBoxModeProperty; public static readonly DependencyProperty NormalColorProperty; public static readonly DependencyProperty ChangedColorProperty; public static readonly DependencyProperty WarningColorProperty; private bool m_AllowEmpty = true; private bool m_AllowBackgroundChange = true; public static readonly DependencyProperty MaxValueProperty; public static readonly DependencyProperty MinValueProperty; public static readonly DependencyProperty AccuracyProperty; public static readonly DependencyProperty TextSavedProperty; public static readonly DependencyProperty ScrollToEndProperty; public static readonly DependencyProperty IsTextboxFocusedProperty; public EditBoxMode EditBoxMode { get { return (EditBoxMode)GetValue(EditBoxModeProperty); } set { SetValue(EditBoxModeProperty, value); } } public Brush NormalColor { get { return (Brush)GetValue(NormalColorProperty); } set { SetValue(NormalColorProperty, value); } } public Brush ChangedColor { get { return (Brush)GetValue(ChangedColorProperty); } set { SetValue(ChangedColorProperty, value); } } public Brush WarningColor { get { return (Brush)GetValue(WarningColorProperty); } set { SetValue(WarningColorProperty, value); } } public bool AllowEmpty { get { return m_AllowEmpty; } set { m_AllowEmpty = value; } } public bool AllowBackgroundChange { get { return m_AllowBackgroundChange; } set { m_AllowBackgroundChange = value; } } public double MaxValue { get { return (double)GetValue(MaxValueProperty); } set { SetValue(MaxValueProperty, value); } } public double MinValue { get { return (double)GetValue(MinValueProperty); } set { SetValue(MinValueProperty, value); } } public int Accuracy { get { return (int)GetValue(AccuracyProperty); } set { SetValue(AccuracyProperty, value); } } public bool TextSaved { get { return (bool)GetValue(TextSavedProperty); } set { SetValue(TextSavedProperty, value); } } public bool IsScrollToEnd { get { return (bool)GetValue(ScrollToEndProperty); } set { SetValue(ScrollToEndProperty, value); } } public bool IsTextboxFocused { get { return (bool)GetValue(IsTextboxFocusedProperty); } set { SetValue(IsTextboxFocusedProperty, value); } } public event KeyEventHandler TextBoxExEnterKeyDown; public override void OnApplyTemplate() { base.OnApplyTemplate(); } static TextBoxEx() { EditBoxModeProperty = DependencyProperty.Register("EditBoxMode", typeof(EditBoxMode), typeof(TextBoxEx), new UIPropertyMetadata(EditBoxMode.Default)); NormalColorProperty = DependencyProperty.Register("NormalColor", typeof(Brush), typeof(TextBoxEx)); ChangedColorProperty = DependencyProperty.Register("ChangedColor", typeof(Brush), typeof(TextBoxEx)); WarningColorProperty = DependencyProperty.Register("WarningColor", typeof(Brush), typeof(TextBoxEx)); MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(TextBoxEx), new UIPropertyMetadata(double.NaN)); MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(TextBoxEx), new UIPropertyMetadata(double.NaN)); AccuracyProperty = DependencyProperty.Register("Accuracy", typeof(int), typeof(TextBoxEx), new UIPropertyMetadata(4)); TextSavedProperty = DependencyProperty.Register("TextSaved", typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(true, TextSavedChangedCallBack)); ScrollToEndProperty = DependencyProperty.Register("IsScrollToEnd", typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(false)); IsTextboxFocusedProperty = DependencyProperty.Register("IsTextboxFocused", typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(false)); FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBoxEx), new FrameworkPropertyMetadata(typeof(TextBoxEx))); } protected override void OnPreviewKeyDown(KeyEventArgs e) { switch (EditBoxMode) { case EditBoxMode.Email: break; case EditBoxMode.SignInteger: AllowInteger(e); break; case EditBoxMode.UnSignInteger: AllowUnsignInteger(e); break; case EditBoxMode.Decimal: AllowDecimal(e); break; case EditBoxMode.UnSignDecimal: AllowUnSignDecimal(e); break; case EditBoxMode.Time: AllowTime(e); break; case EditBoxMode.FileName: AllowFileName(e); break; } } private void AllowInteger(KeyEventArgs e) { int num; if ((Keyboard.Modifiers == ModifierKeys.None || Keyboard.Modifiers == ModifierKeys.Shift) && e.Key != Key.Back && e.Key != Key.Delete && e.Key != Key.Insert && e.Key != Key.Down && e.Key != Key.Left && e.Key != Key.Right && e.Key != Key.Up && e.Key != Key.Tab && e.Key != Key.Next && e.Key != Key.Prior && e.Key != Key.Return && e.Key != Key.Return && e.Key != Key.Escape && e.Key != Key.Home) { num = ((e.Key == Key.End) ? 1 : 0); goto IL_00ae; } num = 1; goto IL_00ae; IL_00ae: bool flag = (byte)num != 0; bool flag2 = e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9; bool flag3 = e.Key >= Key.D0 && e.Key <= Key.D9; if ((flag3 | flag2) && Keyboard.Modifiers != 0) { e.Handled = true; return; } if (e.Key == Key.OemMinus || e.Key == Key.Subtract) { if (Keyboard.Modifiers != ModifierKeys.Shift) { if (base.Text.IndexOfAny(new char[1] { '-' }, 0) == -1 && base.CaretIndex == 0) { flag = true; goto IL_017c; } e.Handled = true; return; } flag = false; } goto IL_017c; IL_017c: e.Handled = (!flag && !flag3 && !flag2); } private void AllowUnsignInteger(KeyEventArgs e) { bool flag = e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9; bool flag2 = e.Key >= Key.D0 && e.Key <= Key.D9; if ((flag2 | flag) && Keyboard.Modifiers != 0) { e.Handled = true; return; } int num; if ((Keyboard.Modifiers == ModifierKeys.None || Keyboard.Modifiers == ModifierKeys.Shift) && e.Key != Key.Back && e.Key != Key.Delete && e.Key != Key.Insert && e.Key != Key.Down && e.Key != Key.Left && e.Key != Key.Right && e.Key != Key.Up && e.Key != Key.Tab && e.Key != Key.Next && e.Key != Key.Prior && e.Key != Key.Return && e.Key != Key.Return && e.Key != Key.Escape && e.Key != Key.Home) { num = ((e.Key == Key.End) ? 1 : 0); goto IL_0106; } num = 1; goto IL_0106; IL_0106: bool flag3 = (byte)num != 0; e.Handled = (!flag3 && !flag2 && !flag); } private void AllowDecimal(KeyEventArgs e) { int num; if ((Keyboard.Modifiers == ModifierKeys.None || Keyboard.Modifiers == ModifierKeys.Shift) && e.Key != Key.Back && e.Key != Key.Delete && e.Key != Key.Insert && e.Key != Key.Down && e.Key != Key.Left && e.Key != Key.Right && e.Key != Key.Up && e.Key != Key.Tab && e.Key != Key.Next && e.Key != Key.Prior && e.Key != Key.Return && e.Key != Key.Return && e.Key != Key.Escape && e.Key != Key.Home) { num = ((e.Key == Key.End) ? 1 : 0); goto IL_00ae; } num = 1; goto IL_00ae; IL_00ae: bool flag = (byte)num != 0; bool flag2 = e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9; bool flag3 = e.Key >= Key.D0 && e.Key <= Key.D9; if ((flag3 | flag2) && Keyboard.Modifiers != 0) { e.Handled = true; return; } if (e.Key == Key.OemMinus || e.Key == Key.Subtract) { if (Keyboard.Modifiers != ModifierKeys.Shift) { if (base.Text.IndexOfAny(new char[1] { '-' }, 0) == -1 && base.CaretIndex == 0) { flag = true; goto IL_0181; } e.Handled = true; return; } flag = false; } goto IL_0181; IL_0181: if (e.Key == Key.OemPeriod || e.Key == Key.Decimal) { if (Keyboard.Modifiers != ModifierKeys.Shift) { if (base.Text.IndexOfAny(new char[1] { '.' }, 0) == -1 && base.CaretIndex > 0 && base.CaretIndex + Accuracy >= base.Text.Length) { flag = true; goto IL_0213; } e.Handled = true; return; } flag = false; } goto IL_0213; IL_0213: int num2 = base.Text.IndexOf('.'); if (num2 > -1 && base.CaretIndex > num2 && base.Text.Length - num2 > Accuracy) { flag3 = (flag2 = false); } e.Handled = (!flag && !flag3 && !flag2); } private void AllowUnSignDecimal(KeyEventArgs e) { bool flag = e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9; bool flag2 = e.Key >= Key.D0 && e.Key <= Key.D9; if ((flag2 | flag) && Keyboard.Modifiers != 0) { e.Handled = true; return; } int num; if ((Keyboard.Modifiers == ModifierKeys.None || Keyboard.Modifiers == ModifierKeys.Shift) && e.Key != Key.Back && e.Key != Key.Delete && e.Key != Key.Insert && e.Key != Key.Down && e.Key != Key.Left && e.Key != Key.Right && e.Key != Key.Up && e.Key != Key.Tab && e.Key != Key.Next && e.Key != Key.Prior && e.Key != Key.Return && e.Key != Key.Return && e.Key != Key.Escape && e.Key != Key.Home) { num = ((e.Key == Key.End) ? 1 : 0); goto IL_0108; } num = 1; goto IL_0108; IL_0108: bool flag3 = (byte)num != 0; if (e.Key == Key.OemPeriod || e.Key == Key.Decimal) { if (Keyboard.Modifiers != ModifierKeys.Shift) { if (base.Text.IndexOfAny(new char[1] { '.' }, 0) == -1 && base.CaretIndex > 0 && base.CaretIndex + Accuracy >= base.Text.Length) { flag3 = true; goto IL_019b; } e.Handled = true; return; } flag3 = false; } goto IL_019b; IL_019b: int num2 = base.Text.IndexOf('.'); if (num2 > -1 && base.CaretIndex > num2 && base.Text.Length - num2 > Accuracy) { flag2 = (flag = false); } e.Handled = (!flag3 && !flag2 && !flag); } private void AllowTime(KeyEventArgs e) { AllowDecimal(e); if (e.Key == Key.Oem1 && Keyboard.Modifiers == ModifierKeys.Shift) { e.Handled = false; } if (e.Key == Key.OemMinus || e.Key == Key.Subtract) { e.Handled = true; } } private void AllowFileName(KeyEventArgs e) { if (base.Text.Length >= 128) { e.Handled = true; } else if (Keyboard.Modifiers == ModifierKeys.Shift && (e.Key == Key.OemPeriod || e.Key == Key.OemComma || e.Key == Key.D8 || e.Key == Key.Oem1 || e.Key == Key.Oem7)) { e.Handled = true; } else if (e.Key == Key.Oem2 || e.Key == Key.Oem5) { e.Handled = true; } } public bool IsOutOfRange() { if (!double.IsNaN(MinValue) && !double.IsNaN(MaxValue)) { double result; bool flag = double.TryParse(base.Text, out result); if (result > MaxValue) { return true; } if (result < MinValue) { return true; } return false; } return false; } protected override void OnLostFocus(RoutedEventArgs e) { base.OnLostFocus(e); IsTextboxFocused = false; if (base.Text.Length == 0) { if (!AllowEmpty) { base.Text = m_strOldValue; } } else if (EditBoxMode == EditBoxMode.UnSignDecimal || EditBoxMode == EditBoxMode.Decimal || EditBoxMode == EditBoxMode.SignInteger || EditBoxMode == EditBoxMode.UnSignInteger) { if (IsOutOfRange()) { base.Background = Brushes.Red; base.ToolTip = MinValue + "-" + MaxValue; } else { SetBGColor(this); } } } protected override void OnKeyDown(KeyEventArgs e) { if (e.Key == Key.Tab) { SelectAll(); } KeyEventHandler textBoxExEnterKeyDown = this.TextBoxExEnterKeyDown; if (textBoxExEnterKeyDown != null && e.Key == Key.Return) { if (IsOutOfRange()) { base.Background = Brushes.Red; base.ToolTip = MinValue + "-" + MaxValue; } else { textBoxExEnterKeyDown(this, e); } } if (e.Key == Key.Return || e.Key == Key.Return) { if (IsOutOfRange()) { base.Background = Brushes.Red; base.ToolTip = MinValue + "-" + MaxValue; } else { SetBGColor(this); } } } protected override void OnTextChanged(TextChangedEventArgs e) { base.OnTextChanged(e); if (base.IsInitialized) { if (m_strOldValue != base.Text && base.IsFocused && AllowBackgroundChange) { TextSaved = false; } else { m_strOldValue = base.Text; TextSaved = true; } if (EditBoxMode == EditBoxMode.FileName) { Regex regex = new Regex("\\*|\\\\|\\/|\\?|\"|:|\\<|\\>|\\|"); base.Text = regex.Replace(base.Text, string.Empty); } } if (IsScrollToEnd) { ScrollToEnd(); } } protected override void OnMouseDown(MouseButtonEventArgs e) { base.OnMouseDown(e); if (e.ClickCount == 1) { SelectAll(); } } protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e) { base.OnGotKeyboardFocus(e); IsTextboxFocused = true; } private static void TextSavedChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs args) { TextBoxEx textBoxEx = d as TextBoxEx; if (textBoxEx != null) { if (textBoxEx.IsOutOfRange()) { textBoxEx.Background = Brushes.Red; textBoxEx.ToolTip = textBoxEx.MinValue + "-" + textBoxEx.MaxValue; } else { SetBGColor(textBoxEx); } } } private static void SetBGColor(TextBoxEx tb) { if (tb.TextSaved) { tb.m_strOldValue = tb.Text; if (tb.NormalColor != null) { tb.Background = tb.NormalColor; } } else if (tb.ChangedColor != null) { tb.Background = tb.ChangedColor; } } public void SaveText() { TextSaved = true; } } }