Return to Snippet

Revision: 65266
at November 13, 2013 18:30 by dck11


Initial Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Controls;
using System.Windows.Input;

namespace TestTextBox
{
   public class NumericTextBoxValidator : Behavior<TextBox>
   {

      public Type TargetType { get; set; }

      protected override void OnAttached()
      {
         base.OnAttached();

         AssociatedObject.Unloaded += ue_Unloaded;
         AssociatedObject.PreviewKeyDown += ue_PreviewKeyDown;
         AssociatedObject.PreviewTextInput += ue_PreviewTextInput;
      }

      protected override void OnDetaching()
      {
         AssociatedObject.Unloaded -= ue_Unloaded;
         AssociatedObject.PreviewKeyDown -= ue_PreviewKeyDown;
      }

      private void ue_PreviewTextInput(object sender, TextCompositionEventArgs e)
      {
         if (TargetType != null)
         {
            try
            {
               var resultingText = this.AssociatedObject.Text.Insert(this.AssociatedObject.CaretIndex, e.Text);
               Convert.ChangeType(resultingText, TargetType);
            }
            catch (Exception)
            {
               e.Handled = true;
            }
         }
      }

      private void ue_Unloaded(object sender, RoutedEventArgs e)
      {
         var ue = sender as FrameworkElement;
         if (ue == null) return;

         ue.Unloaded -= ue_Unloaded;
         ue.PreviewKeyDown -= ue_PreviewKeyDown;
      }

      private void ue_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
      {
         var ue = AssociatedObject;
         if (e.Key == Key.Space)
         {
            e.Handled = true;
         }

         if (!IsKeyADigit(e.Key) && !IsKeyAllowedChar(e.Key) && e.Key != Key.Delete && e.Key != Key.Back && !IsNavigationKey(e.Key) && !IsControlKey(e.Key))
         {
            e.Handled = true;
         }

         if (e.Key == Key.Back || e.Key == Key.Delete)
         {
            if (ue.SelectedText.Length == ue.Text.Length)
            {
               ue.Text = null;
               e.Handled = true;
               return;
            }

            if (ue.Text.Length == 1)
            {
               ue.Text = null;
               e.Handled = true;
            }
         }
         else if ((IsKeyADigit(e.Key) || IsKeyAllowedChar(e.Key)) && ue.SelectedText.Length == ue.Text.Length)
         {
            ue.Text = null;
            if (e.Key == Key.OemMinus || e.Key == Key.Subtract)
            {
               ue.Text = "-";
               ue.SelectionStart = 1;
               e.Handled = true;
            }
            else if (e.Key == Key.OemPeriod || e.Key == Key.OemComma || e.Key == Key.Decimal)
            {
               ue.Text = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
               ue.SelectionStart = 1;
               e.Handled = true;
            }

         }
      }

      private bool IsControlKey(Key key)
      {
         return key == Key.LeftCtrl || key == Key.RightCtrl || key == Key.RightAlt || key == Key.LeftAlt ||
                key == Key.RightShift || key == Key.LeftShift;
      }

      private bool IsNavigationKey(Key key)
      {
         return key == Key.Left || key == Key.Right || key == Key.Return || key == Key.Down || key == Key.Up;
      }

      public static bool IsKeyADigit(Key key)
      {
         return (key >= Key.D0 && key <= Key.D9) || (key >= Key.NumPad0 && key <= Key.NumPad9);
      }

      public static bool IsKeyAllowedChar(Key key)
      {
         return (key == Key.OemMinus || key == Key.Subtract || key == Key.OemPeriod || key == Key.OemComma || key == Key.Decimal);
      }
   }
}

Initial URL


Initial Description
behavior for validating numeric input

Initial Title
Numeric input validator behavior

Initial Tags
c#

Initial Language
C#