zoukankan      html  css  js  c++  java
  • wpf MaskedTextBox

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    
    namespace MyWPFCustomControls
    {
        public class MaskedTextBox : TextBox
        {
    
            public static readonly DependencyProperty InputMaskProperty;
    
            private List<InputMaskChar> _maskChars;
            private int _caretIndex;
    
            static MaskedTextBox()
            {
                TextProperty.OverrideMetadata(typeof(MaskedTextBox),
                    new FrameworkPropertyMetadata(null, new CoerceValueCallback(Text_CoerceValue)));
                InputMaskProperty = DependencyProperty.Register("InputMask", typeof(string), typeof(MaskedTextBox),
                    new PropertyMetadata(string.Empty, new PropertyChangedCallback(InputMask_Changed)));
            }
    
            public MaskedTextBox()
            {
                this._maskChars = new List<InputMaskChar>();
                DataObject.AddPastingHandler(this, new DataObjectPastingEventHandler(MaskedTextBox_Paste));
            }
    
            /// <summary>
            /// Get or Set the input mask.
            /// </summary>
            public string InputMask
            {
                get { return this.GetValue(InputMaskProperty) as string; }
                set { this.SetValue(InputMaskProperty, value); }
            }
    
            [Flags]
            protected enum InputMaskValidationFlags
            {
                None = 0,
                AllowInteger = 1,
                AllowDecimal = 2,
                AllowAlphabet = 4,
                AllowAlphanumeric = 8
            }
    
            /// <summary>
            /// Returns a value indicating if the current text value is valid.
            /// </summary>
            /// <returns></returns>
            public bool IsTextValid()
            {
                string value;
                return this.ValidateTextInternal(this.Text, out value);
            }
    
            private class InputMaskChar
            {
    
                private InputMaskValidationFlags _validationFlags;
                private char _literal;
    
                public InputMaskChar(InputMaskValidationFlags validationFlags)
                {
                    this._validationFlags = validationFlags;
                    this._literal = (char)0;
                }
    
                public InputMaskChar(char literal)
                {
                    this._literal = literal;
                }
    
                public InputMaskValidationFlags ValidationFlags
                {
                    get { return this._validationFlags; }
                    set { this._validationFlags = value; }
                }
    
                public char Literal
                {
                    get { return this._literal; }
                    set { this._literal = value; }
                }
    
                public bool IsLiteral()
                {
                    return (this._literal != (char)0);
                }
    
                public char GetDefaultChar()
                {
                    return (this.IsLiteral()) ? this.Literal : '_';
                }
    
            }
    
            protected override void OnInitialized(EventArgs e)
            {
                base.OnInitialized(e);
    
                //DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(TextProperty, typeof(TextBox));
                //if (dpd != null)
                //{
                //    dpd.AddValueChanged(this, delegate
                //    {
                //        this.UpdateInputMask();
                //    });
                //}
    
            }
    
            protected override void OnMouseUp(MouseButtonEventArgs e)
            {
                base.OnMouseUp(e);
                this._caretIndex = this.CaretIndex;
            }
    
            protected override void OnPreviewKeyDown(KeyEventArgs e)
            {
                base.OnKeyDown(e);
    
                //no mask specified, just function as a normal textbox
                if (this._maskChars.Count == 0)
                    return;
    
                if (e.Key == Key.Delete)
                {
                    //delete key pressed: delete all text
                    this.Text = this.GetDefaultText();
                    this._caretIndex = this.CaretIndex = 0;
                    e.Handled = true;
                }
                else
                {
                    //backspace key pressed
                    if (e.Key == Key.Back)
                    {
                        if (this._caretIndex > 0 || this.SelectionLength > 0)
                        {
                            if (this.SelectionLength > 0)
                            {
                                //if one or more characters selected, delete them
                                this.DeleteSelectedText();
                            }
                            else
                            {
                                //if no characters selected, shift the caret back to the previous non-literal char and delete it
                                this.MoveBack();
    
                                char[] characters = this.Text.ToCharArray();
                                characters[this._caretIndex] = this._maskChars[this._caretIndex].GetDefaultChar();
                                this.Text = new string(characters);
                            }
    
                            //update the base class caret index, and swallow the event
                            this.CaretIndex = this._caretIndex;
                            e.Handled = true;
                        }
                    }
                    else if (e.Key == Key.Left)
                    {
                        //move back to the previous non-literal character
                        this.MoveBack();
                        e.Handled = true;
                    }
                    else if (e.Key == Key.Right || e.Key == Key.Space)
                    {
                        //move forwards to the next non-literal character
                        this.MoveForward();
                        e.Handled = true;
                    }
                }
            }
    
            protected override void OnPreviewTextInput(TextCompositionEventArgs e)
            {
    
                base.OnPreviewTextInput(e);
    
                //no mask specified, just function as a normal textbox
                if (this._maskChars.Count == 0)
                    return;
    
                this._caretIndex = this.CaretIndex = this.SelectionStart;
    
                if (this._caretIndex == this._maskChars.Count)
                {
                    //at the end of the character count defined by the input mask- no more characters allowed
                    e.Handled = true;
                }
                else
                {
                    //validate the character against its validation scheme
                    bool isValid = this.ValidateInputChar(char.Parse(e.Text),
                        this._maskChars[this._caretIndex].ValidationFlags);
    
                    if (isValid)
                    {
                        //delete any selected text
                        if (this.SelectionLength > 0)
                        {
                            this.DeleteSelectedText();
                        }
    
                        //insert the new character
                        char[] characters = this.Text.ToCharArray();
                        characters[this._caretIndex] = char.Parse(e.Text);
                        this.Text = new string(characters);
    
                        //move the caret on 
                        this.MoveForward();
                    }
    
                    e.Handled = true;
                }
            }
    
            /// <summary>
            /// Validates the specified character against all selected validation schemes.
            /// </summary>
            /// <param name="input"></param>
            /// <param name="validationFlags"></param>
            /// <returns></returns>
            protected virtual bool ValidateInputChar(char input, InputMaskValidationFlags validationFlags)
            {
                bool valid = (validationFlags == InputMaskValidationFlags.None);
    
                if (!valid)
                {
                    Array values = Enum.GetValues(typeof(InputMaskValidationFlags));
    
                    //iterate through the validation schemes
                    foreach (object o in values)
                    {
                        InputMaskValidationFlags instance = (InputMaskValidationFlags)(int)o;
                        if ((instance & validationFlags) != 0)
                        {
                            if (this.ValidateCharInternal(input, instance))
                            {
                                valid = true;
                                break;
                            }
                        }
                    }
                }
    
                return valid;
            }
    
            /// <summary>
            /// Returns a value indicating if the current text value is valid.
            /// </summary>
            /// <returns></returns>
            protected virtual bool ValidateTextInternal(string text, out string displayText)
            {
                if (this._maskChars.Count == 0)
                {
                    displayText = text;
                    return true;
                }
    
                StringBuilder displayTextBuilder = new StringBuilder(this.GetDefaultText());
    
                bool valid = (!string.IsNullOrEmpty(text) &&
                    text.Length <= this._maskChars.Count);
    
                if (valid)
                {
                    for (int i = 0; i < text.Length; i++)
                    {
                        if (!this._maskChars[i].IsLiteral())
                        {
                            if (this.ValidateInputChar(text[i], this._maskChars[i].ValidationFlags))
                            {
                                displayTextBuilder[i] = text[i];
                            }
                            else
                            {
                                valid = false;
                            }
                        }
                    }
                }
    
                displayText = displayTextBuilder.ToString();
    
                return valid;
            }
    
            /// <summary>
            /// Deletes the currently selected text.
            /// </summary>
            protected virtual void DeleteSelectedText()
            {
                StringBuilder text = new StringBuilder(this.Text);
                string defaultText = this.GetDefaultText();
                int selectionStart = this.SelectionStart;
                int selectionLength = this.SelectionLength;
    
                text.Remove(selectionStart, selectionLength);
                text.Insert(selectionStart, defaultText.Substring(selectionStart, selectionLength));
                this.Text = text.ToString();
    
                //reset the caret position
                this.CaretIndex = this._caretIndex = selectionStart;
            }
    
            /// <summary>
            /// Returns a value indicating if the specified input mask character is a placeholder.
            /// </summary>
            /// <param name="character"></param>
            /// <param name="validationFlags">If the character is a placeholder, returns the relevant validation scheme.</param>
            /// <returns></returns>
            protected virtual bool IsPlaceholderChar(char character, out InputMaskValidationFlags validationFlags)
            {
                validationFlags = InputMaskValidationFlags.None;
    
                switch (character.ToString().ToUpper())
                {
                    case "I":
                        validationFlags = InputMaskValidationFlags.AllowInteger;
                        break;
                    case "D":
                        validationFlags = InputMaskValidationFlags.AllowDecimal;
                        break;
                    case "A":
                        validationFlags = InputMaskValidationFlags.AllowAlphabet;
                        break;
                    case "W":
                        validationFlags = (InputMaskValidationFlags.AllowAlphanumeric);
                        break;
                }
    
                return (validationFlags != InputMaskValidationFlags.None);
            }
    
            /// <summary>
            /// Invoked when the coerce value callback is invoked.
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="e"></param>
            private static object Text_CoerceValue(DependencyObject obj, object value)
            {
                MaskedTextBox mtb = (MaskedTextBox)obj;
    
                if (value == null || value.Equals(string.Empty))
                    value = mtb.GetDefaultText();
                else if (value.ToString().Length > 0)
                {
                    string displayText;
                    mtb.ValidateTextInternal(value.ToString(), out displayText);
                    value = displayText;
                }
    
                return value;
            }
    
            /// <summary>
            /// Invoked when the InputMask dependency property reports a change.
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="e"></param>
            private static void InputMask_Changed(DependencyObject obj, DependencyPropertyChangedEventArgs e)
            {
                (obj as MaskedTextBox).UpdateInputMask();
            }
    
            /// <summary>
            /// Invokes when a paste event is raised.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void MaskedTextBox_Paste(object sender, DataObjectPastingEventArgs e)
            {
                //TODO: play nicely here?
                //
    
                if (e.DataObject.GetDataPresent(typeof(string)))
                {
                    string value = e.DataObject.GetData(typeof(string)).ToString();
                    string displayText;
    
                    if (this.ValidateTextInternal(value, out displayText))
                    {
                        this.Text = displayText;
                    }
                }
    
                e.CancelCommand();
            }
    
            /// <summary>
            /// Rebuilds the InputMaskChars collection when the input mask property is updated.
            /// </summary>
            private void UpdateInputMask()
            {
    
                string text = this.Text;
                this._maskChars.Clear();
    
                this.Text = string.Empty;
    
                string mask = this.InputMask;
    
                if (string.IsNullOrEmpty(mask))
                    return;
    
                InputMaskValidationFlags validationFlags = InputMaskValidationFlags.None;
    
                for (int i = 0; i < mask.Length; i++)
                {
                    bool isPlaceholder = this.IsPlaceholderChar(mask[i], out validationFlags);
    
                    if (isPlaceholder)
                    {
                        this._maskChars.Add(new InputMaskChar(validationFlags));
                    }
                    else
                    {
                        this._maskChars.Add(new InputMaskChar(mask[i]));
                    }
                }
    
                string displayText;
                if (text.Length > 0 && this.ValidateTextInternal(text, out displayText))
                {
                    this.Text = displayText;
                }
                else
                {
                    this.Text = this.GetDefaultText();
                }
            }
    
            /// <summary>
            /// Validates the specified character against its input mask validation scheme.
            /// </summary>
            /// <param name="input"></param>
            /// <param name="validationType"></param>
            /// <returns></returns>
            private bool ValidateCharInternal(char input, InputMaskValidationFlags validationType)
            {
                bool valid = false;
    
                switch (validationType)
                {
                    case InputMaskValidationFlags.AllowInteger:
                    case InputMaskValidationFlags.AllowDecimal:
                        int i;
                        if (validationType == InputMaskValidationFlags.AllowDecimal &&
                            input == '.' && !this.Text.Contains('.'))
                        {
                            valid = true;
                        }
                        else
                        {
                            valid = int.TryParse(input.ToString(), out i);
                        }
                        break;
                    case InputMaskValidationFlags.AllowAlphabet:
                        valid = char.IsLetter(input);
                        break;
                    case InputMaskValidationFlags.AllowAlphanumeric:
                        valid = (char.IsLetter(input) || char.IsNumber(input));
                        break;
                }
    
                return valid;
            }
    
            /// <summary>
            /// Builds the default display text for the control.
            /// </summary>
            /// <returns></returns>
            private string GetDefaultText()
            {
                StringBuilder text = new StringBuilder();
                foreach (InputMaskChar maskChar in this._maskChars)
                {
                    text.Append(maskChar.GetDefaultChar());
                }
                return text.ToString();
            }
    
            /// <summary>
            /// Moves the caret forward to the next non-literal position.
            /// </summary>
            private void MoveForward()
            {
                int pos = this._caretIndex;
                while (pos < this._maskChars.Count)
                {
                    if (++pos == this._maskChars.Count || !this._maskChars[pos].IsLiteral())
                    {
                        this._caretIndex = this.CaretIndex = pos;
                        break;
                    }
                }
            }
    
            /// <summary>
            /// Moves the caret backward to the previous non-literal position.
            /// </summary>
            private void MoveBack()
            {
                int pos = this._caretIndex;
                while (pos > 0)
                {
                    if (--pos == 0 || !this._maskChars[pos].IsLiteral())
                    {
                        this._caretIndex = this.CaretIndex = pos;
                        break;
                    }
                }
            }
        }
    }

    xmal:

    View Code
      <CustomControl:MaskedTextBox Width="100" Height="20" Margin="87,150,316,142" InputMask="dd/dd/dddd"/>
  • 相关阅读:
    把ssl模块加入到已经编译好的apache中实现HTTPS
    六,集合
    一. 计算机语言基础知识:
    三, 字符串
    四,列表的使用方法
    hash()函数的用法
    五,字典用法总结
    十,编码
    七八九,条件和循环语句
    二.Python的基础语法知识
  • 原文地址:https://www.cnblogs.com/FaDeKongJian/p/2949144.html
Copyright © 2011-2022 走看看