【问题标题】:Why can't I leave a TextBox using tab?为什么我不能使用选项卡离开文本框?
【发布时间】:2012-02-14 06:35:53
【问题描述】:

我有这个代码:

public static void AddDefaultTextFromTag(params TextBox[] textBoxes)
{
    foreach (TextBox oTextBox in textBoxes)
    {
        bool isPasswordChar = oTextBox.UseSystemPasswordChar;

        oTextBox.Enter += (sndr, evnt) =>
        {
            if (((TextBox)sndr).Text == ((TextBox)sndr).Tag.ToString())
            {
                ((TextBox)sndr).Text = "";
                ((TextBox)sndr).UseSystemPasswordChar = isPasswordChar;
                ((TextBox)sndr).ForeColor = SystemColors.WindowText;
            }
        };

        oTextBox.Leave += (sndr, evnt) =>
        {
            if (((TextBox)sndr).Text.Trim().Count() == 0)
            {
                ((TextBox)sndr).UseSystemPasswordChar = false;
                ((TextBox)sndr).CharacterCasing = CharacterCasing.Normal;
                ((TextBox)sndr).Text = ((TextBox)sndr).Tag.ToString();
                ((TextBox)sndr).ForeColor = SystemColors.GrayText;
            }
        };

        if (oTextBox.Text.Trim().Count() == 0)
        {
            oTextBox.UseSystemPasswordChar = false;
            oTextBox.CharacterCasing = CharacterCasing.Normal;
            oTextBox.Text = oTextBox.Tag.ToString();
            oTextBox.ForeColor = SystemColors.GrayText;
        }
    }
}

但是当我在这个方法的参数中输入的TextBox.UseSystemPasswordChar为真且TextBox.Text属性为空时,TextBox不能使用键盘上的Tab按钮离开,只有MouseClick可以习惯于失去那个TextBox的焦点。

为什么会这样?

我的代码在 C#,框架 4,在 VS2010 Pro 中构建,项目在 WinForms 中。 我使用 VS ToolBox 中的 TextBox。

请帮忙。提前致谢。

【问题讨论】:

  • 只是一个建议:为什么不创建两个方法(Enter 和 Leave)并将其作为事件处理程序附加到所有文本框,而不是为每个文本框使用自定义委托? (我认为在这种情况下它们不会被重用,但我不确定)您可以在所有这些上运行 Leave 事件处理程序,而不是复制代码。
  • @Joey 匿名方法是绝对重用的。在编译期间,每个匿名方法都被转换为类的实例方法,并且该方法用于事件处理程序。所以别担心:)
  • 啊,谢谢 MD.Unicorn。然后可以忽略那部分,只使用减少代码重复的最后一个建议;)

标签: c# winforms .net-4.0


【解决方案1】:

您无法离开文本框的原因是您正在更改文本框中的 CharacterCasing 属性。

不知道为什么它会这样工作,但它以前发生在我身上,我最终做的是捕获按键事件,如果它是一个字母,我会将它切换为它的大写值。这不是最佳的,但它有效

我做了类似的事情(从头顶写出来,但应该可以):

void YourTextbox_KeyPress(object sender, KeyPressEventArgs e)
{
    if (char.IsLetter(e.KeyChar))
    {
        if (this.CharacterCasing == CharacterCasing.Upper && char.IsLower(e.KeyChar))
        {
            this.Text = this.Text.Insert(this.SelectionStart, char.ToUpper(e.KeyChar) + string.Empty);
            this.SelectionStart++;
            e.Handled = true;
        }
        else if (this.CharacterCasing == System.Windows.Forms.CharacterCasing.Lower && char.IsUpper(e.KeyChar))
        {
            this.Text = this.Text.Insert(this.SelectionStart, char.ToLower(e.KeyChar) + string.Empty);
            this.SelectionStart++;
            e.Handled = true;
        }
    }
}

您还应该使用 new 关键字来“覆盖”(我知道这不是正确的术语)字符大小写,所以它不会做自己的事情

public new CharacterCasing CharacterCasing { get; set; }

代码基本上检查按下的键是否是字母,然后,如果它被标记为Upper,并且字符是小写,则将其替换为它的大写版本(在光标的位置),然后将光标移动到下一个部分,反之亦然(toLower)

注意: 如果用户选择了多个字符(SelectionLenght > 0),此代码可能(应该)有一些问题,如果您想保留正常的文本框功能,您应该删除所有选定的字符

【讨论】:

    【解决方案2】:

    所以我设置了一个 WinForms 应用程序,绘制了两个文本框,将一个设置为 UseSystemPasswordChar=true 然后设置如下:

        private void Form1_Load(object sender, EventArgs e)
        {
            textBox2.Tag = "test2";
            textBox1.Tag = "test1";
    
            TextBox[] tb = { textBox1, textBox2 };
            AddDefaultTextFromTag(tb);
        }
    

    您的功能运行良好,无论文本框包含什么内容,我都可以轻松浏览表单上的控件。 (添加了一个按钮,也对选项卡测试没有任何作用)所以...除非我的测试设置无效,否则没有复制

    【讨论】:

    • 我从工具箱中拖动工具。 TabIndex 由 VS 自动设置,TabStop 设置为 true。
    【解决方案3】:

    我在post 的答案中找到了适合我的解决方案。您可以将 PasswordChar 设置为 '●' 然后设置为 '\0' 以获得普通文本,而不是将 UseSystemPasswordChar 设置为 true 然后设置为 false。您不应设置 UseSystemPasswordChar,因为它优先于 PasswordChar。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-09
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多