Click here to Skip to main content
15,891,423 members
Articles / Desktop Programming / WPF

Custom WPF TextBox which allows input based on the data type or a Regular Expression

Rate me:
Please Sign up or sign in to vote.
1.00/5 (1 vote)
4 Jan 2012CPOL2 min read 24.2K   666   6  
Extending the WPF textbox to permit only numeric (for int and float) and regex.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace MOWPFCustomControls
{
    public class MaskTextBox : TextBox
    {
        public static DependencyProperty DataTypeProperty =
   DependencyProperty.Register("DataType", typeof(string), typeof(MaskTextBox), new PropertyMetadata("string"));
        public static DependencyProperty RegExProperty =
  DependencyProperty.Register("RegEx", typeof(string), typeof(MaskTextBox), new PropertyMetadata("string"));


        public string DataType
        {
            get { return (string)GetValue(DataTypeProperty); }
            set { SetValue(DataTypeProperty, value); }
        }

        public string RegEx
        {
            get { return (string)GetValue(RegExProperty); }
            set { SetValue(RegExProperty, value); }
        }

        public MaskTextBox()
            : base()
        {
            EventManager.RegisterClassHandler(
                typeof(MaskTextBox),
                DataObject.PastingEvent,
                (DataObjectPastingEventHandler)((sender, e) =>
                                                     {
                                                         if (!IsDataValid(e.DataObject))
                                                         {
                                                             DataObject data = new DataObject();
                                                             data.SetText(String.Empty);
                                                             e.DataObject = data;
                                                             e.Handled = false;
                                                         }
                                                     }));
            this.AddHandler(MaskTextBox.PreviewKeyDownEvent, new RoutedEventHandler(PreviewKeyDownEventHandler));
            this.AddHandler(MaskTextBox.LostFocusEvent, new RoutedEventHandler(LostFocusEventHandler));
        }

        public void LostFocusEventHandler(object sender, RoutedEventArgs e)
        {
            if (this.Text == "-")
                this.Text = string.Empty;
        }

        public void PreviewKeyDownEventHandler(object sender, RoutedEventArgs e)
        {
            KeyEventArgs ke = e as KeyEventArgs;
            if (ke.Key == Key.Space)
            {
                ke.Handled = true;
            }
        }

        protected override void OnDrop(DragEventArgs e)
        {
            e.Handled = !IsDataValid(e.Data);
            base.OnDrop(e);
        }

        protected override void OnDragOver(DragEventArgs e)
        {
            if (!IsDataValid(e.Data))
            {
                e.Handled = true;
                e.Effects = DragDropEffects.None;
            }
            base.OnDragEnter(e);
        }

        private Boolean IsDataValid(
            IDataObject data)
        {
            Boolean isValid = false;
            if (data != null)
            {
                String text = data.GetData(DataFormats.Text) as String;
                if (!String.IsNullOrEmpty(text == null ? null : text.Trim()))
                {
                    switch (DataType)
                    {
                        case "INT":
                            Int32 result = -1;
                            if (Int32.TryParse(text.Trim(), out result))
                            {
                                if (result > 0)
                                {
                                    isValid = true;
                                }
                            }
                            break;

                        case "FLOAT":
                            float floatResult = -1;
                            if (float.TryParse(text.Trim(), out floatResult))
                            {
                                if (floatResult > 0)
                                {
                                    isValid = true;
                                }
                            }
                            break;
                        case "RegEx":
                            if (System.Text.RegularExpressions.Regex.IsMatch(text, RegEx))
                            {
                                isValid = true;
                            }
                            break;

                    }
                }
            }
            return isValid;
        }


        protected override void OnPreviewTextInput(TextCompositionEventArgs e)
        {
            string text = this.Text;
            text = text.Insert(this.CaretIndex, e.Text);
            switch (DataType)
            {
                case "INT":
                    Int32 result = -1;
                    if (!Int32.TryParse(text.Trim(), out result))
                    {
                        if (!text.Equals("-"))
                            e.Handled = true;
                    }
                    break;

                case "FLOAT":
                    float floatResult = -1;
                    if (!float.TryParse(text.Trim(), out floatResult))
                    {
                        if (!text.Equals("-"))
                            e.Handled = true;
                    }
                    break;
                case "RegEx":
                    if (!System.Text.RegularExpressions.Regex.IsMatch(text, RegEx))
                    {
                        e.Handled = true;
                    }
                    break;
            }
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions