当标签失控时,启用其后的禁用控制,以便焦点转到该控件,而不是跳过它?

时间:2015-05-12 13:51:16

标签: c# winforms

由于用户点击Tab键而离开文本框之前,我想启用一个跟随它的控件,以便它成为焦点控件。

相反,似乎Winforms已经决定焦点会在哪里,所以它会跳过控制。

我已尝试使用ValidatingValidated事件启用后续控件,但似乎这太晚了,即使我知道如果验证表明失败,焦点也不会离开控件如此清晰,标签行为可能会在验证时受到影响。

因此,示例特定场景(代码如下):

  1. 3个控件,文本框+复选框+文本框
  2. 复选框已停用,焦点目前位于第一个文本框
  3. 作为离开第一个文本框的一部分,我想验证它的内容,如果确定,我想启用复选框
  4. 因此,如果用户位于第一个文本框中,使用有效数据填充,并点击Tab,则焦点现在应位于复选框上,而不是第二个文本框上。
  5. 观察到的行为是焦点移动到第二个文本框,跳过复选框,并且复选框已启用,可能不是按此顺序(即,我描述观察到的最终结果,不一定是事情发生的顺序) )。

    有可能得到我想要的东西吗?

    这是一个演示问题的LINQPad程序

    void Main()
    {
        var fm = new Form();
    
        var e1 = new TextBox();
        e1.Location = new Point(8, 8);
        e1.CausesValidation = true;
        e1.TabIndex = 0;
        e1.TabStop = true;
    
        var chk = new CheckBox();
        chk.Text = "Checkbox";
        chk.Location = new Point(8, e1.Bottom + 8);
        chk.Enabled = false;
        chk.TabIndex = 1;
        chk.TabStop = true;
    
        var e2 = new TextBox();
        e2.Location = new Point(8, chk.Bottom + 8);
        e2.TabIndex = 2;
        e2.TabStop = true;
    
        fm.Controls.Add(e1);
        fm.Controls.Add(chk);
        fm.Controls.Add(e2);
    
        e1.Validating += (s, e) =>
        {
            Debug.WriteLine("e1 validating");
            chk.Enabled = true;
        };
    
        e1.Validated += (s, e) =>
        {
            Debug.WriteLine("e1 validated");
            chk.Enabled = true;
        };
    
        chk.Enter += (s, e) => Debug.WriteLine("chk entered");
        e2.Enter += (s, e) => Debug.WriteLine("e2 entered");
    
        fm.ShowDialog();
    }
    

2 个答案:

答案 0 :(得分:0)

一个黑客的排序。但是工作..

e1.Leave += (s, e) =>
    {
        Debug.WriteLine("e1 Leave");
        chk.Enabled = true;
        fm.SelectNextControl( e1,true,true,true,true);
    };

答案 1 :(得分:0)

您最好在TextChanged事件中验证输入,例如:

e1.TextChanged += (s, e) =>
{
    chk.Enabled = (e1.Text.Length > 2);
};

Control.Validating event的MSDN文档包含此警告:

  

请勿尝试从Enter,GotFocus,Leave,LostFocus,Validating或Validated事件处理程序中设置焦点。这样做可能会导致您的应用程序或操作系统停止响应。有关更多信息,请参阅"键盘输入参考"中的WM_KILLFOCUS主题。部分,以及"消息死锁" "关于消息和消息队列" MSDN库中http://msdn.microsoft.com/library的主题。

我不记得Windows使用处理消息的具体顺序,但我怀疑启用chk复选框的消息会在 Windows处理Tab键后发送。在TextChanged事件中进行验证意味着您不必担心这种奇怪的竞争状况。