How do I get a TextBox to only accept numeric input in WPF?

后端 未结 30 2962
悲哀的现实
悲哀的现实 2020-11-22 03:40

I\'m looking to accept digits and the decimal point, but no sign.

I\'ve looked at samples using the NumericUpDown control for Windows Forms, and this sample of a Num

30条回答
  •  我寻月下人不归
    2020-11-22 03:58

    This is an improved solution of WilPs answer. My improvements are:

    • Improved behaviour on Del and Backspace buttons
    • Added EmptyValue property, if empty string is inappropriate
    • Fixed some minor typos
    /// 
    ///     Regular expression for Textbox with properties: 
    ///         , 
    ///         ,
    ///         .
    /// 
    public class TextBoxInputRegExBehaviour : Behavior
    {
        #region DependencyProperties
        public static readonly DependencyProperty RegularExpressionProperty =
            DependencyProperty.Register("RegularExpression", typeof(string), typeof(TextBoxInputRegExBehaviour), new FrameworkPropertyMetadata(".*"));
    
        public string RegularExpression
        {
            get { return (string)GetValue(RegularExpressionProperty); }
            set { SetValue(RegularExpressionProperty, value); }
        }
    
        public static readonly DependencyProperty MaxLengthProperty =
            DependencyProperty.Register("MaxLength", typeof(int), typeof(TextBoxInputRegExBehaviour),
                                            new FrameworkPropertyMetadata(int.MinValue));
    
        public int MaxLength
        {
            get { return (int)GetValue(MaxLengthProperty); }
            set { SetValue(MaxLengthProperty, value); }
        }
    
        public static readonly DependencyProperty EmptyValueProperty =
            DependencyProperty.Register("EmptyValue", typeof(string), typeof(TextBoxInputRegExBehaviour), null);
    
        public string EmptyValue
        {
            get { return (string)GetValue(EmptyValueProperty); }
            set { SetValue(EmptyValueProperty, value); }
        }
        #endregion
    
        /// 
        ///     Attach our behaviour. Add event handlers
        /// 
        protected override void OnAttached()
        {
            base.OnAttached();
    
            AssociatedObject.PreviewTextInput += PreviewTextInputHandler;
            AssociatedObject.PreviewKeyDown += PreviewKeyDownHandler;
            DataObject.AddPastingHandler(AssociatedObject, PastingHandler);
        }
    
        /// 
        ///     Deattach our behaviour. remove event handlers
        /// 
        protected override void OnDetaching()
        {
            base.OnDetaching();
    
            AssociatedObject.PreviewTextInput -= PreviewTextInputHandler;
            AssociatedObject.PreviewKeyDown -= PreviewKeyDownHandler;
            DataObject.RemovePastingHandler(AssociatedObject, PastingHandler);
        }
    
        #region Event handlers [PRIVATE] --------------------------------------
    
        void PreviewTextInputHandler(object sender, TextCompositionEventArgs e)
        {
            string text;
            if (this.AssociatedObject.Text.Length < this.AssociatedObject.CaretIndex)
                text = this.AssociatedObject.Text;
            else
            {
                //  Remaining text after removing selected text.
                string remainingTextAfterRemoveSelection;
    
                text = TreatSelectedText(out remainingTextAfterRemoveSelection)
                    ? remainingTextAfterRemoveSelection.Insert(AssociatedObject.SelectionStart, e.Text)
                    : AssociatedObject.Text.Insert(this.AssociatedObject.CaretIndex, e.Text);
            }
    
            e.Handled = !ValidateText(text);
        }
    
        /// 
        ///     PreviewKeyDown event handler
        /// 
        void PreviewKeyDownHandler(object sender, KeyEventArgs e)
        {
            if (string.IsNullOrEmpty(this.EmptyValue))
                return;
    
            string text = null;
    
            // Handle the Backspace key
            if (e.Key == Key.Back)
            {
                if (!this.TreatSelectedText(out text))
                {
                    if (AssociatedObject.SelectionStart > 0)
                        text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart - 1, 1);
                }
            }
            // Handle the Delete key
            else if (e.Key == Key.Delete)
            {
                // If text was selected, delete it
                if (!this.TreatSelectedText(out text) && this.AssociatedObject.Text.Length > AssociatedObject.SelectionStart)
                {
                    // Otherwise delete next symbol
                    text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, 1);
                }
            }
    
            if (text == string.Empty)
            {
                this.AssociatedObject.Text = this.EmptyValue;
                if (e.Key == Key.Back)
                    AssociatedObject.SelectionStart++;
                e.Handled = true;
            }
        }
    
        private void PastingHandler(object sender, DataObjectPastingEventArgs e)
        {
            if (e.DataObject.GetDataPresent(DataFormats.Text))
            {
                string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text));
    
                if (!ValidateText(text))
                    e.CancelCommand();
            }
            else
                e.CancelCommand();
        }
        #endregion Event handlers [PRIVATE] -----------------------------------
    
        #region Auxiliary methods [PRIVATE] -----------------------------------
    
        /// 
        ///     Validate certain text by our regular expression and text length conditions
        /// 
        ///  Text for validation 
        ///  True - valid, False - invalid 
        private bool ValidateText(string text)
        {
            return (new Regex(this.RegularExpression, RegexOptions.IgnoreCase)).IsMatch(text) && (MaxLength == int.MinValue || text.Length <= MaxLength);
        }
    
        /// 
        ///     Handle text selection
        /// 
        /// true if the character was successfully removed; otherwise, false. 
        private bool TreatSelectedText(out string text)
        {
            text = null;
            if (AssociatedObject.SelectionLength <= 0) 
                return false;
    
            var length = this.AssociatedObject.Text.Length;
            if (AssociatedObject.SelectionStart >= length)
                return true;
    
            if (AssociatedObject.SelectionStart + AssociatedObject.SelectionLength >= length)
                AssociatedObject.SelectionLength = length - AssociatedObject.SelectionStart;
    
            text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, AssociatedObject.SelectionLength);
            return true;
        }
        #endregion Auxiliary methods [PRIVATE] --------------------------------
    }
    

    Usage is pretty straightforward:

    
        
    
    

提交回复
热议问题