如何防止在文本框中使用退格键?

6

我希望能够在文本框中禁止某些按键,如果我只想允许使用退格键,可以使用以下代码:

    private void KeyBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        e.Handled = true;
    }

然而,我只想在按下“退格”键时抑制按键。 我使用以下代码:
        if (e.Key == System.Windows.Input.Key.Back)
        {
            e.Handled = true;
        }

然而,这并不起作用。选择起点后面的字符仍然被删除。输出中我确实得到了“TRUE”,所以Back键被识别了。我该如何防止用户按退格键?(我的原因是有时我想删除单词而不是字符,因此需要自己处理退格键按下事件)。

难道没有像“PreviewKeyDown”这样的事件吗? - Honza Brestan
Silverlight for Windows Phone没有PreviewKeyDown的实现。 - Den
8个回答

15

当您想要抑制按键时,只需在KeyDown事件中设置e.SuppressKeyPress = true。例如,使用以下代码防止退格键更改文本框中的文本:

只需在KeyDown事件中设置e.SuppressKeyPress = true即可抑制按键。

例如,使用以下代码防止退格键更改文本框中的文本:

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Back)
    {
        e.SuppressKeyPress = true;
    }
}

请注意,如果您尝试在 txtBox1_KeyUp() 处理程序中执行此操作,它将似乎无法正常工作(因为KeyDown已经处理了TextBox的事件)。


3
在Silverlight中,没有办法处理系统按键事件,例如退格键。因此,您可以检测到它,但不能手动处理它。

1
这需要我们在按键按下事件之前存储文本框的值。不幸的是,退格键在该事件被触发之前处理,因此我们必须在此之前捕获它,然后在键盘松开事件被处理后再次更新它。
    private string textBeforeChange;

    private void TextBox1_OnKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Back)
        {
            e.Handled = true;
            textBox1.Text = textBeforeChange;
        }
    }

    private void TextBox1_OnKeyUp(object sender, KeyEventArgs e)
    {
        textBeforeChange = textBox1.Text;
    }

    private void MainPage_OnLoaded(object sender, RoutedEventArgs e)
    {
        textBox1.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(TextBox1_OnKeyDown), true);
        textBox1.AddHandler(TextBox.KeyUpEvent, new KeyEventHandler(TextBox1_OnKeyUp), true);
        textBox1.AddHandler(TextBox.ManipulationStartedEvent, new EventHandler<ManipulationStartedEventArgs>(TextBox1_OnManipulationStarted), true);
    }

    private void TextBox1_OnManipulationStarted(object sender, ManipulationStartedEventArgs e)
    {
        textBeforeChange = textBox1.Text;
    }

0

虽然处理这种情况没有简单的方法,但是有可能。

您需要在类中创建一些成员变量,以存储输入文本、光标位置和回退键按下状态的状态,当我们在KeyDown、TextChanged和KeyUp事件之间跳转时。

代码应该类似于这样:

    string m_TextBeforeTheChange;
    int m_CursorPosition = 0;
    bool m_BackPressed = false;

    private void KeyBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        m_TextBeforeTheChange = KeyBox.Text;
        m_BackPressed = (e.Key.Equals(System.Windows.Input.Key.Back)) ? true : false;
    }

    private void KeyBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (m_BackPressed)
        {
            m_CursorPosition = KeyBox.SelectionStart;
            KeyBox.Text = m_TextBeforeTheChange;
        }
    }

    private void KeyBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        KeyBox.SelectionStart = (m_BackPressed) ? m_CursorPosition + 1 : KeyBox.SelectionStart;
    }

被接受的解决方案并不是最好的。更好的建议请参见下面链接:https://dev59.com/Bm_Xa4cB1Zd3GeqP1HEL#18062836,使用e.SuppressKeyPress。 - tofo

0
    string oldText = "";
    private void testTextBlock_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (testTextBlock.Text.Length < oldText.Length)
        {
            testTextBlock.Text = oldText;
            testTextBlock.SelectionStart = oldText.Length;
        }
        else
        {
            oldText = testTextBlock.Text;
        }
    }

0

这是我想出来的删除前一个单词(CtrlBackspace)和后一个单词(CtrlDelete)的方法,同时处理多个连续的空格字符(0x09、0x20、0xA0):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DeleteWord
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            // Tab, space, line feed
            char[] whitespace = {'\x09', '\x20', '\xA0'};
            string text = textBox1.Text;
            int start = textBox1.SelectionStart;

            if ((e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete) && textBox1.SelectionLength > 0)
            {
                e.SuppressKeyPress = true;
                textBox1.Text = text.Substring(0, start) + text.Substring(start + textBox1.SelectionLength);
                textBox1.SelectionStart = start;
                return;
            }

            else if (e.KeyCode == Keys.Back && e.Control)
            {
                e.SuppressKeyPress = true;

                if (start == 0) return;

                int pos = Math.Max(text.LastIndexOfAny(whitespace, start - 1), 0);

                while (pos > 0)
                {
                    if (!whitespace.Contains(text[pos]))
                    {
                        pos++;
                        break;
                    }
                    pos--;
                }

                textBox1.Text = text.Substring(0, pos) + text.Substring(start);
                textBox1.SelectionStart = pos;
            }
            else if (e.KeyCode == Keys.Delete && e.Control)
            {
                e.SuppressKeyPress = true;

                int last = text.Length - 1;

                int pos = text.IndexOfAny(whitespace, start);
                if (pos == -1) pos = last + 1;

                while (pos <= last)
                {
                    if (!whitespace.Contains(text[pos])) break;
                    pos++;
                }

                textBox1.Text = text.Substring(0, start) + text.Substring(pos);
                textBox1.SelectionStart = start;
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Tab)
            {
                textBox1.Paste("\t");
                return true;
            }
            else if (keyData == (Keys.Shift | Keys.Tab))
            {
                textBox1.Paste("\xA0");
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

    }
}

感谢 Huy Nguyen 提供的 e.SuppressKeyPress = true;

如果有选定内容,无论修饰键如何,删除和退格键都将删除选定内容(您不会得到那个丑陋的矩形字符,因为按住 Ctrl

似乎对于像 这样的字符也有效,尽管这可能没有太多意义(这个字符不是一个完整的单词吗?)


0

这是一个对我有效的简单解决方案。

private void MyTxtbox_Keypress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == '\b')
    {
        e.Handled = true;

        return;
    }
}

0

只需将此文本放置在textBox(例如:textBox18)的KeyDown事件中:

    private void textBox18_KeyDown(object sender, KeyEventArgs e)
    {
        e.SuppressKeyPress = true;      // cancels the typed character
        if (e.KeyValue != 8)            // checks if key typed is Backspace 
        {
            e.SuppressKeyPress = false; // if it is not Backspace then reactivates/enables the typed character
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接