C# 控件。输入事件不';切换任务时不要开火。有没有其他方法可以做到这一点?

C# 控件。输入事件不';切换任务时不要开火。有没有其他方法可以做到这一点?,c#,events,user-interface,C#,Events,User Interface,代表步骤: 创建.NET表单应用程序示例 在表单上放置一个文本框 将函数连接到TextBox的Enter事件 运行此应用程序时,当焦点第一次转到文本框时,将触发控件.Enter事件。但是,如果您单击其他应用程序,然后单击返回测试应用程序,事件将不会再次触发 因此,在应用程序之间移动不会触发进入/离开 我是否可以使用另一个可选的控制级别事件,在这种情况下将触发该事件 通常,我会使用Form.Activated。不幸的是,这在这里很麻烦,因为我的组件是由一个停靠系统托管的,该系统可以在不通知我的情况

代表步骤:

  • 创建.NET表单应用程序示例
  • 在表单上放置一个文本框
  • 将函数连接到TextBox的Enter事件
  • 运行此应用程序时,当焦点第一次转到文本框时,将触发控件.Enter事件。但是,如果您单击其他应用程序,然后单击返回测试应用程序,事件将不会再次触发

    因此,在应用程序之间移动不会触发进入/离开

    我是否可以使用另一个可选的控制级别事件,在这种情况下将触发该事件


    通常,我会使用Form.Activated。不幸的是,这在这里很麻烦,因为我的组件是由一个停靠系统托管的,该系统可以在不通知我的情况下将我的组件卸载到一个新表单中。

    在Enter事件中,您试图做什么

    我找不到在您的示例程序中触发的另一个控件级事件,但当我的测试应用程序确实重新获得焦点时,最后一个拥有焦点的控件仍然拥有它


    有趣的问题,但它需要更多的上下文。

    在您的示例中,我认为您需要另一个控件。原因是第一个控件(tabIndex 0)是具有焦点的控件。由于没有其他控件可切换焦点,此控件将始终处于焦点状态,因此永远无法进入。切换到另一个应用程序或窗体不会更改此窗体中的焦点或活动控件,因此返回时仍不会触发事件


    添加控件后,control.entered应该可以正常工作。如果这是您唯一的控件,为什么不在窗体获得焦点时在formLoad或TextChanged上调用该事件?

    谢谢,我将提供一些背景信息

    我的控件是一个UserControl,它包含一个网格和一个工具栏。用户通常会启动其中几个控件来查看系统数据的不同部分

    有几个键盘快捷键可以从当前网格中的选定行启动操作。但是,要求这些键盘快捷键不仅应用于当前聚焦的网格。如果用户当前正专注于应用程序的许多其他区域之一,则此键盘快捷键仍应有效,并应将其路由到上次聚焦的网格

    所以我给控件连接了一个函数。输入UserControl的event,基本上就是LastFocusedGrid=this

    它会工作的,除了对接和脱离

    请参见,这些控件托管在具有停靠功能的应用程序中,有点类似于VisualStudio

    默认情况下,该控件作为应用程序主工作区内的选项卡启动,类似于在VisualStudio中打开源文件的方式

    但是,用户可以通过抓取选项卡标题并将其从主应用程序中拖出来“翻出”选项卡。此时,应用程序将创建一个新的“float表单”来承载控件。在主应用程序和此浮动窗体之间切换与在应用程序之间切换相同,用于控制.Enter和form.Activated事件

    在这一点上,我们有了“表单中的一个控件”场景,该场景使用原始文章中描述的示例应用程序进行了模拟

    现在,有一些方法可以解决这个问题。我可以利用Form.Activated事件,它在表单之间切换时会触发。如果将测试应用程序中的事件添加到表单的激活事件中,您将看到它工作得非常好

    问题是我的UserControl与其父窗体的关系是不稳定的,这使得解决方案有些复杂。我试着连接到“this.ParentForm.Activated”,效果很好。问题是你什么时候叫它?当您解除连接/重新连接时会发生什么?我最终得到了一堆糟糕的代码,比如“previousParentForm”,这样我就可以从旧表单上取下,然后我仍然面临这样的问题:当我的父表单被更改时,对接系统不会通知我,所以我也不得不在那里做一系列更改

    这些问题并不是无法解决的,但如果有一个更简单的控制级别“父窗体被激活”事件,那么这将更加优雅


    这相当长,但我希望它能澄清问题。

    因此,在创建网格时,您不能设置KeyPressed或KeyUp等事件吗?如果是这样,所有网格都可以使用相同的事件处理程序。只要确保在进入事件处理程序时执行以下操作:

    Grid currentGrid = (Grid)sender;
    
    然后,您应该能够将该代码块应用于发送进来的任何网格,而不必担心跟踪


    因为所有的事件处理程序都是真实的,所以只要执行它所需的一切都是可访问的,它的位置就是一个静音点。

    Frye,问题是无论用户在应用程序中的何处,键盘快捷键都应该工作。它们是gloabl命令,在顶层处理,然后路由到“最后一个焦点网格”

    因此,在网格级别处理击键没有帮助

    更具体地说,假设用户启动了网格A、B和C,但他也启动了与我的代码无关的其他控件X、Y和Z


    用户先单击A,然后单击C。然后单击Y,然后单击Z。当焦点位于Z时,他点击我的键盘快捷键。在这种情况下,网格C应该响应,因为它是用户关注的最后一个网格。

    听起来您遇到的问题与Enter事件没有直接关系,更重要的是,如果您有控件“与代码无关”那么你真的不是在看控制级事件。

    我想我不清楚

    我的控件位于容器应用程序中。其他团队的其他无关控制也是如此。把它想象成VisualStudio--我的控件
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Windows.Forms;
    
        namespace EnterBrokenExample
        {
            static class Program
            {
                /// <summary>
                /// The main entry point for the application.
                /// </summary>
                [STAThread]
                static void Main()
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
    
                    Form Form1 = new Form();
                    Form c1 = new Form();
                    Form c2 = new Form();
    
                    Form1.IsMdiContainer = true;
    
                    c1.MdiParent = Form1;
                    c2.MdiParent = Form1;
    
                    c1.Show();
                    c2.Show();
    
                    TextBox tb1 = new TextBox();
                    c1.Controls.Add(tb1);
                    tb1.Enter += ontbenter;
                    tb1.Text = "Some Text";
                    tb1.GotFocus += ongotfocus;
    
                    TextBox tb2 = new TextBox();
                    c2.Controls.Add(tb2);
                    tb2.Enter += ontbenter;
                    tb2.Text = "some other text";
                    tb2.GotFocus += ongotfocus;
    
                    Application.Run(Form1);
                }
                static void ontbenter(object sender, EventArgs args)
                {
                    if (!(sender is TextBox))
                        return;
                    TextBox s = (TextBox)sender;
                    s.SelectAll();
                }
    
                static void ongotfocus(object sender, EventArgs args)
                {
                    if (!(sender is TextBox))
                        return;
                    TextBox s = (TextBox)sender;
                    s.SelectAll();
                }
            }
        }