切换任务时,Control.Enter事件不会触发。有替代方案吗?

时间:2008-09-30 22:25:17

标签: c# events user-interface

代表步骤:

  1. 创建示例.NET表单应用程序
  2. 在表单
  3. 上放置一个TextBox
  4. 将函数连接到TextBox的Enter事件
  5. 运行此应用程序时,焦点首次转到TextBox时会触发 Control.Enter 事件。但是,如果您单击另一个应用程序,然后单击返回测试应用程序,该事件将不会再次触发。

    因此在应用程序之间移动不会触发Enter / Leave

    我可以使用另一个替代控制级事件,在这种情况下会触发吗?

    通常,我会使用 Form.Activated 。不幸的是,这在这里很麻烦,因为我的组件由一个对接系统托管,可以在不通知我的情况下将我的组件拆分成新的表单。

9 个答案:

答案 0 :(得分:3)

你想在Enter事件中做什么?

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

有趣的问题,但它需要更多的背景。

答案 1 :(得分:1)

如果我尝试您的示例并在另一个窗口,桌面等控件外部单击,我可以触发Got和Lost Focus事件,但如果您只是尝试在窗体或控件中单击1控制,这些事件从不被解雇,因为它是唯一需要关注的事情。既不会进入也不会离开,除非你改变动态或超载控件,否则你无法实现这一点

答案 2 :(得分:0)

在您的示例中,我认为您需要另一个控件。原因是第一个控件(tabIndex 0)是具有焦点的控件。由于没有其他控制来切换焦点,因此该控件将始终聚焦,因此永远无法输入。切换到另一个应用程序或表单不会改变此表单中的焦点或活动控件,因此当您返回时,仍然不会触发该事件。

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

答案 3 :(得分:0)

谢谢,我会给出一些背景知识。

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

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

所以我将一个函数连接到UserControl的Control.Enter事件,基本上说LastFocusedGrid = this。

它会起作用,除了对接和解除对接......

请注意,这些控件托管在具有停靠功能的应用程序中,有点类似于visual studio。

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

但是,用户可以通过抓取选项卡标题并将其拖出主应用程序来“删除”选项卡。此时,应用程序创建一个新的“浮动窗体”来托管控件。为了Control.Enter和Form.Activated事件的目的,在主应用程序和此浮动窗体之间切换与在应用程序之间切换相同。

此时我们使用原始帖子中描述的示例应用程序模拟了“表单中的一个控件”场景。

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

问题在于我的UserControl与其父Form的关系是流动的,使得解决方案有点复杂。我尝试连线到“this.ParentForm.Activated”,这工作正常。问题是你什么时候打电话给这个?当您脱离/重新锁定时会发生什么?我最后得到一堆令人讨厌的代码,例如“previousParentForm”,这样我就可以从旧表单中解脱,然后我仍然面临着当我的父表单被更改时对接系统没有通知我的问题,所以我不得不在那里做一些改变。

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

那是相当长的,但我希望它能澄清情况。

答案 4 :(得分:0)

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

Grid currentGrid = (Grid)sender;

然后,您应该能够将该代码块应用于任何已发送的网格,而无需担心跟踪。

由于所有事件处理程序确实存在,只要您执行它所需的一切都可以访问,它的位置就是一个静音点。

答案 5 :(得分:0)

Frye,问题是无论用户在应用程序中的哪个位置,键盘快捷键都应该有效。它们是gloabl命令,在顶层处理,然后路由到“最后聚焦网格”。

因此,处理网格级别的击键无济于事。

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

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

猜猜我不清楚。

我的控件存在于容器应用程序中。其他团队的其他无关控制也是如此。想象它就像visual studio - 我的控件是代码编辑选项卡,但是还有待处理的更改列表和属性窗口,它们与源文件共存但不直接相关。

键盘快捷键由容器应用程序处理。然后它应该被路由到用户关注的最后一个控件。

维护这个“LastFocusedGrid”引用是我在Enter事件中所做的。

如果你想在visual studio中看到类似的功能,试试这个:

  1. 打开一些源文件
  2. 导航至“起始页”标签。
  3. 点击Ctrl-F并在“当前文档”中搜索某些字符串
  4. 请注意,serach功能会自动导航到LAST FOCUSED源文件以执行搜索。
  5. 因此,即使您没有专注于源文件,ctrl-F命令也由visual studio处理并路由到最后一个聚焦源文件选项卡。

    现在用Ctrl-G尝试相同的操作。除非您直接关注源文件,否则它不起作用。

    我的键盘命令需要像Ctrl-F一样工作,而不是像Ctrl-G一样。这就是为什么我不直接在我的控制中捕获键盘事件。

    这会澄清或使事情变得更糟吗?

答案 8 :(得分:0)

您是否尝试过一个简单的Control.GotFocus?