【问题标题】:Input handling in WinFormWinForm 中的输入处理
【发布时间】:2010-09-22 14:48:44
【问题描述】:

什么是阻止某些输入键在 TextBox 中使用而不阻止特殊击键的最佳方法,例如 Ctrl-V/Ctrl kbd>-C?

例如,只允许用户输入字符或数字的子集,例如 A、B 或 C,仅此而已。

【问题讨论】:

    标签: c# winforms keyboard user-input


    【解决方案1】:

    如果密钥不被允许,我会使用 keydown-event 并使用 e.cancel 来停止密钥。如果我想在多个地方执行此操作,那么我将创建一个继承文本框的用户控件,然后添加一个属性 AllowedChars 或 DisallowedChars 为我处理它。我有几个变体,我不时使用,一些允许货币格式化和输入,一些用于时间编辑等等。

    将它作为用户控件的好处是您可以添加到它并使其成为您自己的杀手文本框。 ;)

    【讨论】:

      【解决方案2】:

      我使用Masked Textbox 控制winforms。对此有更长的解释here。本质上,它不允许与字段条件不匹配的输入。如果您不希望人们输入除数字之外的任何内容,那么它根本不允许他们输入除数字之外的任何内容。

      【讨论】:

        【解决方案3】:

        这就是我通常的处理方式。

        Regex regex = new Regex("[0-9]|\b");            
        e.Handled = !(regex.IsMatch(e.KeyChar.ToString()));
        

        这将只允许数字字符和退格。问题是在这种情况下您将不被允许使用控制键。如果您想保留该功能,我会创建自己的文本框类。

        【讨论】:

        • Ed:我已经在使用正则表达式,并且需要扩展文本框以允许 ctrl 键。我在 KeyPress 事件中将 Backspace 和 Delete 作为特殊情况处理,KeyPress 事件是否在正确的位置进行键检查/阻止
        【解决方案4】:

        我发现唯一可行的解​​决方案是在 ProcessCmdKey 中对 Ctrl-VCtrl 的按键进行预检查 - C、Delete 或 Backspace,如果它不是 KeyPress 事件中的这些键之一,则使用正则表达式进行进一步验证。

        这可能不是最好的方法,但它在我的情况下有效。

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            // check the key to see if it should be handled in the OnKeyPress method
            // the reasons for doing this check here is:
            // 1. The KeyDown event sees certain keypresses differently, e.g NumKeypad 1 is seen as a lowercase A
            // 2. The KeyPress event cannot see Modifer keys so cannot see Ctrl-C,Ctrl-V etc.
            // The functionality of the ProcessCmdKey has not changed, it is simply doing a precheck before the 
            // KeyPress event runs
            switch (keyData)
            {
                case Keys.V | Keys.Control :
                case Keys.C | Keys.Control :
                case Keys.X | Keys.Control :
                case Keys.Back :
                case Keys.Delete :
                    this._handleKey = true;
                    break;
                default:
                    this._handleKey = false;
                    break;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
        
        
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (String.IsNullOrEmpty(this._ValidCharExpression))
            {
                this._handleKey = true;
            }
            else if (!this._handleKey)
            {
                // this is the final check to see if the key should be handled
                // checks the key code against a validation expression and handles the key if it matches
                // the expression should be in the form of a Regular Expression character class
                // e.g. [0-9\.\-] would allow decimal numbers and negative, this does not enforce order, just a set of valid characters
                // [A-Za-z0-9\-_\@\.] would be all the valid characters for an email
                this._handleKey = Regex.Match(e.KeyChar.ToString(), this._ValidCharExpression).Success;
            }
            if (this._handleKey)
            {
                base.OnKeyPress(e);
                this._handleKey = false;
            }
            else
            {
                e.Handled = true;
            }
            
        }
        

        【讨论】:

          【解决方案5】:

          您可以为文本框使用 TextChanged 事件。

              private void txtInput_TextChanged(object sender, EventArgs e)
              {
                  if (txtInput.Text.ToUpper() == "A" || txtInput.Text.ToUpper() == "B")
                  {
                      //invalid entry logic here
                  }
              }
          

          【讨论】:

            猜你喜欢
            • 2013-05-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-12
            相关资源
            最近更新 更多