【问题标题】:WinForms: Textbox Leave event doesn't get fired after going to main menuWinForms:进入主菜单后不会触发文本框离开事件
【发布时间】:2020-02-18 18:31:07
【问题描述】:

我的表单上有一个 TextBox 控件。我使用控件上的 Leave 事件来处理用户输入。如果用户单击表单上的其他控件,它可以正常工作,但是当用户直接进入主菜单时,甚至不会被触发。任何想法我应该使用哪个事件来让它每次都被触发?

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    我找到了一个合理的解决方法,我手动将焦点设置在主菜单上:

    编辑:按照@TcKs 的建议,我将事件从ItemClicked 更改为MenuActivate。非常感谢您的帮助!

        private void menuStrip1_MenuActivate( object sender, EventArgs e )
        {
            menuStrip1.Focus();
        }
    

    【讨论】:

    • 它只适用于鼠标,不适用于键盘。请查看我的编辑。
    【解决方案2】:

    您应该使用“Validating”和“Validated”事件来检查用户的输入。 然后,如果用户转到另一个控件“A”,并且控件“A”的属性“CausesValidation”设置为“true”(其默认值),则会触发“Validating”和“Validated”事件。

    菜单也有“CausesValidation”属性。

    编辑: 抱歉,我忘记了菜单条中的“CausesValidation”是我们的功能,而不是内置的。 但是验证检查非常简单:

    private void menuStrip1_MenuActivate( object sender, EventArgs e ) {
        bool ret = this.Validate( false );
        if ( false == ret ) {
            // user's input is wrong
        }
    }
    

    如果您想在“this”表单之外的另一个控件中检查验证,请使用任何 ContainerControl 而不是“this”。例如在 MDI 子窗口中。

    【讨论】:

    • 我在 Toolstripmenuitem 或 menustrip 上找不到 CausesValidating 属性...
    • 我在 Toolstripmenuitem 上也找不到 CausesValidating 属性
    【解决方案3】:

    在某些情况下没有触发 Lostfocus,例如单击工具栏按钮和菜单项。 我过去常常使用本地“LastControl”变量来解决这个问题,并在菜单获得焦点时自己处理它。

    菜单单击不会失去文本框焦点是有原因的。例如,如果您想要一个带有“粘贴”的“编辑”菜单,则“粘贴”应该针对具有焦点的控件进行操作,因此它不能从表单上的任何控件中窃取焦点。

    所以菜单可以看作是一个上下文菜单,不会从控件中窃取焦点。

    【讨论】:

    • 这很公平,菜单不应该从控件中窃取焦点 - 但另一方面,没有机制可以以相当简单的方式处理我的场景。你的方法在简单的情况下是可以的,但是我有一个在不同表单上使用的用户控件层次结构,所以我真的不能拥有 LastControl
    • 是的,我已经准备好发布一个在激活菜单时动态转发 InvokeLostFocus(LastControl) 的示例。但是后来我看到了您使用 menustrip1.focus() 的解决方法,所以我没有。 ;)
    【解决方案4】:

    在玩菜单时,您必须以某种方式模拟失去焦点,并且可能要记住它的位置,以防您关闭菜单而不做任何事情,这样焦点就会返回到文本框

    【讨论】:

      【解决方案5】:

      你需要一个每 1 像素 1 个像素的标签

      Private Sub TextBox1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Leave
          MsgBox("yes")
      End Sub
      
      Private Sub MenuStrip1_MenuActivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuActivate
          CType(sender, MenuStrip).Tag = ActiveControl
          Label1.Focus()
      End Sub
      
      Private Sub MenuStrip1_MenuDeactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuStrip1.MenuDeactivate
          If CType(sender, MenuStrip).Tag Is Control AndAlso CType(CType(sender, MenuStrip).Tag, Control).CanFocus Then
              CType(CType(sender, MenuStrip).Tag, Control).Focus()
          End If
          CType(sender, MenuStrip).Tag = Nothing
      End Sub
      

      【讨论】:

      • 我知道是VB.Net代码,但在C#下应该是一样的逻辑
      • 似乎不起作用 - ActiveControl 是我点击的菜单项:(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多