Wednesday, May 14, 2014

Numeric Textbox in WPF

public class TextBoxHelpers : DependencyObject
    {
        public static bool GetIsNumeric(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsNumericProperty);
        }

        public static void SetIsNumeric(DependencyObject obj, bool value)
        {
            obj.SetValue(IsNumericProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsNumeric.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsNumericProperty =
         DependencyProperty.RegisterAttached("IsNumeric", typeof(bool), typeof(TextBoxHelpers), new PropertyMetadata(false, new PropertyChangedCallback((s, e) =>
         {
             TextBox targetTextbox = s as TextBox;
             if (targetTextbox != null)
             {
                 if ((bool)e.OldValue && !((bool)e.NewValue))
                 {
                     targetTextbox.PreviewTextInput -= targetTextbox_PreviewTextInput;

                 }
                 if ((bool)e.NewValue)
                 {
                     targetTextbox.PreviewTextInput += targetTextbox_PreviewTextInput;
                     targetTextbox.PreviewKeyDown += targetTextbox_PreviewKeyDown;
                 }
             }
         })));

        static void targetTextbox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            e.Handled = e.Key == Key.Space;
        }

        static void targetTextbox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            TextBox tb = sender as TextBox;

            Char newChar = e.Text.ToString()[0];
            if (newChar != '.')
            {
                e.Handled = !Char.IsNumber(newChar);
            }
            else
            {
                e.Handled = tb.Text.Contains('.');
            }
        }
    }

xaml Page:

xmlns:ui="clr-namespace:Reluce.ServiceTracker.Helpers"  

<TextBox
            Name="txtQty"
            Grid.Row="4"
            Grid.Column="1"
            Margin="2"
            HorizontalAlignment="Left"           
            FontSize="12"
            AcceptsReturn="False"
            Width="120" 
            ui:TextBoxHelpers.IsNumeric="True"

Focus to next Control in wpf on Enter key event

public static class FocusAdvancement
    {
        public static bool GetAdvancesByEnterKey(DependencyObject obj)
        {
            return (bool)obj.GetValue(AdvancesByEnterKeyProperty);
        }

        public static void SetAdvancesByEnterKey(DependencyObject obj, bool value)
        {
            obj.SetValue(AdvancesByEnterKeyProperty, value);
        }

        public static readonly DependencyProperty AdvancesByEnterKeyProperty =
            DependencyProperty.RegisterAttached("AdvancesByEnterKey", typeof(bool), typeof(FocusAdvancement),
            new UIPropertyMetadata(OnAdvancesByEnterKeyPropertyChanged));

        static void OnAdvancesByEnterKeyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as UIElement;
            if (element == null) return;

            if ((bool)e.NewValue) element.KeyDown += Keydown;
            else element.KeyDown -= Keydown;
        }

        static void Keydown(object sender, KeyEventArgs e)
        {
            if (!e.Key.Equals(Key.Enter)) return;

            var element = sender as UIElement;
            if (element != null) element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        }
    }


in xaml Page:
 xmlns:ui="clr-namespace:Reluce.ServiceTracker.Helpers"

<TextBox
            Name="txtName"
            Grid.Row="1"
            Grid.Column="3"
            Margin="2"
            HorizontalAlignment="Left"           
            FontSize="12"
            AcceptsReturn="False"
            Width="120"
            ui:FocusAdvancement.AdvancesByEnterKey="True"
            />