切换任务时不会触发Control.Enter事件。有没有其他选择呢?
代表步骤:
- 创建示例.NET表单应用程序
- 在窗体上放置一个文本框
- 将函数连接到TextBox的Enter事件
当我们运行此应用程序时,首先将焦点移到TextBox时将触发Control.Enter事件。但是,如果我们单击进入另一个应用程序,然后再单击回到测试应用程序,则该事件将不会再次触发。
因此,在应用程序之间移动不会触发Enter / Leave。
我是否可以使用另一个替代的控制级别事件,在这种情况下会触发该事件?
通常,我将使用Form.Activated。不幸的是,这很麻烦,因为我的组件由对接系统托管,该对接系统可以在不通知我的情况下将我的组件停靠到新的Form中。
解决方案
我们打算在Enter事件中做什么?
我找不到在示例程序中触发的另一个控件级别的事件,但是当我的测试应用程序确实重新获得焦点时,最后具有焦点的控件仍然具有它。
有趣的问题,但需要更多上下文。
在示例中,我认为我们需要另一个控件。原因是第一个控件(tabIndex 0)是具有焦点的控件。没有其他控件可以将焦点切换到该控件,则该控件将始终处于焦点状态,因此永远无法输入。切换到另一个应用程序或者表单将不会更改此表单的焦点或者活动控件,因此返回时仍不会触发该事件。
通过添加控件,control.entered应该可以正常工作。如果这是我们唯一的控件,当表单获得焦点时,为什么不在formLoad或者TextChanged上调用事件?
谢谢,我会讲一些背景。
我的控件是一个UserControl,其中包含一个网格和一个工具栏。用户通常会启动这些控件中的几个控件以查看系统数据的不同部分。
有几个键盘快捷键可以启动当前网格中所选行的操作。但是,要求这些键盘快捷方式不仅应应用于当前关注的网格。如果用户当前专注于应用程序的许多其他区域之一,则此键盘快捷方式应该仍然有效,并且应该将其路由到最后一个聚焦的网格。
所以我将一个函数连接到UserControl的Control.Enter事件,基本上说LastFocusedGrid = this。
它会工作,除了对接和取消对接...
可以看到,这些控件托管在具有停靠功能的应用程序内部,与Visual Studio有点类似。
默认情况下,该控件在应用程序的主工作区域内作为选项卡启动,类似于在Visual Studio中打开源文件的方式。
但是,用户可以通过抓住选项卡标题并将其拖出主应用程序来"剥离"选项卡。此时,应用程序将创建一个新的"浮动表格"来托管控件。就Control.Enter和Form.Activated事件而言,在主应用程序和此浮动形式之间进行切换与在应用程序之间进行切换相同。
到那时,我们已经用原始文章中描述的示例应用程序模拟了"表单中的一个控件"场景。
现在,有一些解决方法。我可以利用Form.Activated事件,该事件在表单之间切换时会触发。如果将测试应用程序中的事件添加到窗体的Activated事件,我们将发现它运行良好。
问题是我的UserControl与它的父Form的关系是不稳定的,这使解决方案有些复杂。我尝试将其连接到" this.ParentForm.Activated",效果很好。问题是我们何时称呼它?当我们取消对接/重新对接时会发生什么?我最终得到了像" previousParentForm"之类的令人讨厌的代码,这样我就可以从旧表单上解开,然后我仍然面临这样的问题,即当更改我的父Form时,停靠系统无法通知我,所以我也必须在那里做一堆更改。
这些问题不是无法解决的,但是,如果存在一个更简单的控件级别的"已激活父窗体"事件,那么它将更加优雅。
那是相当长的时间,但是我希望它可以澄清这种情况。
因此,在创建网格时,是否可以不设置KeyPressed或者KeyUp等事件?如果是这样,则所有网格都可以使用相同的事件处理程序。只要确保当我们进入事件处理程序时即可执行以下操作:
Grid currentGrid = (Grid)sender;
然后,我们应该能够将该代码块应用于发送到的任何网格,而不必担心跟踪。
由于所有事件处理程序实际上都是如此,因此只要我们可以执行它所需的所有内容,它的位置就是一个静默点。
Frye,问题在于,无论用户在应用程序中的哪个位置,键盘快捷键都应该起作用。它们是gloabl命令,在顶层处理,然后被路由到"最后关注的网格"。
因此,在网格级别处理击键将无济于事。
更具体地说,假设用户启动了网格A,B和C。但是他还启动了与我的代码无关的其他控件X,Y和Z。
用户单击A,然后单击C。然后单击Y,然后单击Z。将焦点放在Z上,单击我的键盘快捷键。在这种情况下,网格C应该响应,因为它是用户关注的最后一个网格。
听起来好像我们遇到的问题与Enter事件没有直接关系,更重要的是,如果我们拥有"与代码无关的控件",那么我们实际上并没有在关注控件级别的事件。
猜猜我不清楚。
我的控件位于容器应用程序中。其他团队进行的其他无关控制也是如此。可以将其视为Visual Studio,我的控件是"代码编辑"选项卡,但是还有待处理的更改列表和属性窗口,它们与源文件同在,但并不直接相关。
键盘快捷方式由容器应用程序处理。然后,应该将其路由到用户关注的我控件的最后一个。
我在Enter事件中所做的就是维护此" LastFocusedGrid"参考。
如果我们想在Visual Studio中看到类似的功能,请尝试以下操作:
- 打开一些源文件
- 导航到"起始页"标签。
- 按Ctrl-F并在"当前文档"中搜索某些字符串
- 请注意,搜索功能会自动导航到"最后关注的"源文件以执行搜索。
因此,即使我们不关注源文件,ctrl-F命令也由Visual Studio处理,并被路由到最后一个关注的源文件选项卡。
现在,使用Ctrl-G尝试相同的操作。除非我们直接将重点放在源文件上,否则它将无法正常工作。
我的键盘命令在这里需要像Ctrl-F一样工作,而不是Ctrl-G。这就是为什么我不只是直接在控件中捕获键盘事件。
这是否使情况变得更清楚或者更糟?
我们是否尝试过一个简单的Control.GotFocus?
如果我尝试示例并在另一个窗口,桌面等上的控件外部单击,则可以触发Got和Lost Focus事件,但是,如果我们只想在仅包含一个控件的窗体或者控件中单击,这些事件永远不会被解雇,因为这是唯一需要关注的事情。除非更改动力学或者使控件超载,否则都不会进入或者离开,否则将无法实现