WPF 中的屏蔽文本框格式



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

我想做的是

我有一个屏蔽格式,如 XXXX/XXXX/XXXX /XXXX

我希望 XXXX/XXXX

/XXXX/XXXX 字符自动返回到文本框框,如果用户在输入不正确时删除文本框内容。

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

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

MainWindow.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>

我的屏蔽文本框.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);
    }
}

}

我在某处犯了一个错误。错误在哪里?

这是解决方案,它不允许删除分隔标记,并且当您删除某些数字时,它会将其替换为"_"。更改一种方法。 同样在 if for delete 键 I e.Handle 中设置为 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);
}

如果解决方案有效,请告诉我!它对我有用。

最新更新