【问题标题】:How to prevent a backspace key stroke in a TextBox?如何防止文本框中的退格键击键?
【发布时间】:2013-03-09 21:35:32
【问题描述】:

我想抑制文本框中的击键。为了抑制除 Backspace 之外的所有击键,我使用以下命令:

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

但是,我只想在按下的键是 Backspace 时抑制击键。我使用以下内容:

        if (e.Key == System.Windows.Input.Key.Back)
        {
            e.Handled = true;
        }

但是,这不起作用。选择开始后面的字符仍然被删除。我确实在输出中得到“TRUE”,所以 Back 键被识别。如何防止用户按退格键? (我这样做的原因是在某些情况下我想删除单词而不是字符,因此我需要自己处理返回键。)

【问题讨论】:

  • 难道没有像“PreviewKeyDown”这样的事件吗?
  • Silverlight for Windows Phone 没有实现 PreviewKeyDown。

标签: c# windows-phone-7 windows-phone keystroke backspace


【解决方案1】:

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

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

请注意,如果您在 txtBox1_KeyUp() 处理程序中尝试此操作,它似乎不起作用(因为 KeyDown 已经处理了 TextBox 的事件)。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      这要求我们在按键事件之前存储文本框的值。不幸的是,退格是在该事件触发之前处理的,因此我们必须在该事件发生之前捕获它,然后我们可以在处理按键事件后再次更新它。

          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;
          }
      

      【讨论】:

        【解决方案4】:

        确实没有简单的方法来处理这种情况,但有可能。

        当我们在 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;
            }
        

        【讨论】:

        • 公认的解决方案不是最好的。更好的建议below 使用 e.SuppressKeyPress
        【解决方案5】:
            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;
                }
            }
        

        【讨论】:

          【解决方案6】:

          这就是我想出的删除上一个(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;

          如果有选择,无论修饰键如何,Delete 和 Backspace 都会删除选择(按住 Ctrl 不会得到那个丑陋的矩形字符)

          似乎也适用于像? 这样的字符,尽管它可能没有多大意义(这个字符不是一个完整的词吗?)

          【讨论】:

            【解决方案7】:

            这是一个适合我的简单解决方案。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-04-15
              • 2010-12-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-17
              相关资源
              最近更新 更多