代码之家  ›  专栏  ›  技术社区  ›  Enes

WPF中的屏蔽文本框格式

  •  0
  • Enes  · 技术社区  · 6 年前

    我在为WPF做一个文本框屏蔽。删除文本框文本中的字符行时出错。

    我想做的是

    我有一个掩蔽格式 年月日

    我想要 年月日 如果用户在输入错误时删除文本框内容,则字符将自动返回到文本框。

    我可以对用户删除进行分组吗?

    例如,格式XXXX-YYYY-ZZZZ-TTTT。我可以按X,Y,Y,T值删除组吗?

    主窗口.xaml

     <StackPanel Orientation="Horizontal" Width="280">
        <local:MyMaskedTextBox x:Name="MaskedDemo" Mask="0000/0000/0000/0000" StayInFocusUntilValid="True" IgnoreSpace="True" Width="180" Height="26" Margin="20"/>
        <Button Content="OK" Height="24" Width="50"/>
    </StackPanel>
    

    MyMaskedTextBox.cs

    {
    class MyMaskedTextBox : TextBox
    {
        private System.ComponentModel.MaskedTextProvider _mprovider = null;
        public string Mask
        {
            get
            {
                if (_mprovider != null) return _mprovider.Mask;
                else return "";
            }
            set
            {
                _mprovider = new System.ComponentModel.MaskedTextProvider(value);
                this.Text = _mprovider.ToDisplayString();
            }
        }
    
        private bool PreviousInsertState = false;
    
        private bool _InsertIsON = false;
        private bool _stayInFocusUntilValid = true;
    
        /// <summary>
        /// Sets whether the focus should stay on the control until the contents are valid
        /// </summary>
        public bool StayInFocusUntilValid
        {
            get { return _stayInFocusUntilValid; }
            set { _stayInFocusUntilValid = value; }
        }
    
        private bool _NewTextIsOk = false;
        /// <summary>
        /// Defines whether the next entered input text is ok according to the mask
        /// </summary>
        public bool NewTextIsOk
        {
            get { return _NewTextIsOk; }
            set { _NewTextIsOk = value; }
        }
    
        private bool _ignoreSpace = true;
        /// <summary>
        /// Sets whether space should be ignored
        /// </summary>
        public bool IgnoreSpace
        {
            get { return _ignoreSpace; }
            set { _ignoreSpace = value; }
        }
    
        /// <summary>
        /// Stops the effect of some common keys
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            if (this.SelectionLength > 1)
            {
                this.SelectionLength = 0;
                e.Handled = false;
            }
            if (e.Key == Key.Insert || e.Key == Key.Delete || e.Key == Key.Back || (e.Key == Key.Space && _ignoreSpace))
            {
                e.Handled = false;
            }
            base.OnPreviewKeyDown(e);
    
        }
    
        /// <summary>
        /// We check whether we are ok
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
        {
            System.ComponentModel.MaskedTextResultHint hint;
            int TestPosition;
    
            if (e.Text.Length == 1)
                this._NewTextIsOk = _mprovider.VerifyChar(e.Text[0], this.CaretIndex, out hint);
            else
                this._NewTextIsOk = _mprovider.VerifyString(e.Text, out TestPosition, out hint);
    
            base.OnPreviewTextInput(e);
    
        }
    
        /// <summary>
        /// When text is received by the TextBox we check whether to accept it or not
        /// </summary>
        /// <param name="e"></param>
        protected override void OnTextInput(System.Windows.Input.TextCompositionEventArgs e)
        {
            string PreviousText = this.Text;
            if (NewTextIsOk)
            {
                base.OnTextInput(e);
                if (_mprovider.VerifyString(this.Text) == false) this.Text = PreviousText;
                while (!_mprovider.IsEditPosition(this.CaretIndex) && _mprovider.Length > this.CaretIndex) this.CaretIndex++;
    
            }
            else
                e.Handled = false; //true;
        }
    
        /// <summary>
        /// When the TextBox takes the focus we make sure that the Insert is set to Replace
        /// </summary>
        /// <param name="e"></param>
        protected override void OnGotFocus(RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            if (!_InsertIsON)
            {
                PressKey(Key.Insert);
                _InsertIsON = true;
            }
        }
    
        /// <summary>
        /// When the textbox looses the keyboard focus we may want to verify (based on the StayInFocusUntilValid) whether
        /// the control has a valid value (fully complete)
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            if (StayInFocusUntilValid)
            {
                _mprovider.Clear();
                _mprovider.Add(this.Text);
                if (!_mprovider.MaskFull) e.Handled = true;
            }
    
            base.OnPreviewLostKeyboardFocus(e);
        }
    
        /// <summary>
        /// Simulates pressing a key
        /// </summary>
        /// <param name="key">The key to be pressed</param>
        private void PressKey(Key key)
        {
            KeyEventArgs eInsertBack = new KeyEventArgs(Keyboard.PrimaryDevice,
                                                        Keyboard.PrimaryDevice.ActiveSource,
                                                        0, key);
            eInsertBack.RoutedEvent = KeyDownEvent;
            InputManager.Current.ProcessInput(eInsertBack);
        }
    }
    

    }

    我在某个地方犯了个错误。错误在哪里?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Kaspar    6 年前

    这是一个解决方案,它不允许删除分隔标记,而且当您删除某个数字时,它将替换为“\u”。改变一种方法。 同样在if for delete键内,即Handled被设置为true,即不执行删除,只在if语句内实现逻辑。

    protected override void OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e)
    {
        if (this.SelectionLength > 1)
        {
            this.SelectionLength = 0;
            e.Handled = false;
        }
        if (e.Key == Key.Insert || e.Key == Key.Delete || e.Key == Key.Back || (e.Key == Key.Space && _ignoreSpace))
        {
            StringBuilder sb = new StringBuilder(this.Text);
            if (sb[CaretIndex - 1] != '-')
            {
                sb[CaretIndex - 1] = '_';
            }
            this.Text = sb.ToString();
            e.Handled = true;
        }
        base.OnPreviewKeyDown(e);
    }
    

    请让我知道解决方案是否有效!对我有用。