C# 知道谁在失焦事件中获得了焦点

C# 知道谁在失焦事件中获得了焦点,c#,compact-framework,focus,C#,Compact Framework,Focus,有可能知道谁在失去焦点的事件中获得了焦点吗 Compact Framework没有ActiveControl,因此我不知道如何判断谁获得了焦点。否。首先是一个控件的LostFocus事件,然后是下一个控件的GotFocus事件。只要您不能确定用户在下一刻使用哪个控件,这是不可能的。 然而,如果compact framework控件确实具有TabIndex属性,则只有在用户使用tab键时才能预测该属性 编辑: 好吧,你发布了解决方案,效果很好,我必须承认:简单的“不”是错误的 +1一个选项是互操作

有可能知道谁在失去焦点的事件中获得了焦点吗


Compact Framework没有
ActiveControl
,因此我不知道如何判断谁获得了焦点。

否。首先是一个控件的LostFocus事件,然后是下一个控件的GotFocus事件。只要您不能确定用户在下一刻使用哪个控件,这是不可能的。
然而,如果compact framework控件确实具有TabIndex属性,则只有在用户使用tab键时才能预测该属性

编辑: 好吧,你发布了解决方案,效果很好,我必须承认:简单的“不”是错误的
+1

一个选项是互操作GetFocus API

[DllImport("coredll.dll, EntryPoint="GetFocus")]
public extern static IntPtr GetFocus();

这将为您提供当前具有输入焦点的窗口的句柄,然后您可以递归地迭代控件树以查找具有该句柄的控件。

使用corell.dll看起来是个好主意


另一种可能的方法是为窗体上的所有控件创建GotFocus事件处理程序,然后创建一个类级变量,该变量使用具有当前焦点的控件的名称进行更新。

这是最终有效的解决方案:

public System.Windows.Forms.Control FindFocusedControl()
{
    return FindFocusedControl(this);
}

public static System.Windows.Forms.Control FindFocusedControl(System.Windows.Forms.Control container)
{
    foreach (System.Windows.Forms.Control childControl in container.Controls)
    {
        if (childControl.Focused)
        {
            return childControl;
        }
    }

    foreach (System.Windows.Forms.Control childControl in container.Controls)
    {
        System.Windows.Forms.Control maybeFocusedControl = FindFocusedControl(childControl);
        if (maybeFocusedControl != null)
        {
            return maybeFocusedControl;
        }
    }

    return null; // Couldn't find any, darn!
}

这是瓦卡诺回答的较短代码,使用Linq

private static Control FindFocusedControl(Control container)
{
    foreach (Control childControl in container.Controls.Cast<Control>().Where(childControl => childControl.Focused)) return childControl;
    return (from Control childControl in container.Controls select FindFocusedControl(childControl)).FirstOrDefault(maybeFocusedControl => maybeFocusedControl != null);
}
私有静态控件FindFocusedControl(控件容器)
{
foreach(container.Controls.Cast()中的Control-childControl,其中(childControl=>childControl.Focused))返回childControl;
返回(来自容器中的控件childControl。控件选择FindFocusedControl(childControl)).FirstOrDefault(MaybeCocusedControl=>MaybeCocusedControl!=null);
}

完全相同(在高级抽象中)。

请记住,在LostFocus事件中调用GetFocus将导致控件失去焦点,因此虽然GetFocus将为您提供当前控件,但您必须有一些事件来知道何时调用它。@ctacke-哇,听起来。。。复杂。总之,如果我在错误的时间调用GetFocus(如LostFocus事件),它实际上会更改当前焦点,而不仅仅是告诉我什么控件有焦点?所以我很困惑。。。医生说GotFocus在LostFocus之前。但是我看到LostFocus是第一位的(正如你所说的),文档当然是正确的,但是它缺少控制的真正含义。因此,请仔细阅读我所写的内容:一个控件的失去焦点先于下一个控件的获得焦点。MSDN只是说GotFocus位于同一控件的LostFocus之前。你说的是“看见”,所以我假设你举了一个小例子,例如,你在一个列表框中存储了不同控件的Lost-and-Gotfocus事件的发生。啊。。。我现在明白了。好吧,这是有道理的,但我仍然没有找到解决问题的方法。也许描述一下你真正想用它做什么,也许还有其他更好的解决方案?在我的失焦方法中,我想根据获得焦点的控件显示一条消息(或不显示)。我尝试过(请参见此处:)它不起作用(\因为LostFocus位于GotFocus之前(由Oops指示)您已经在下面的回答评论中说明,您希望使用LostFocus事件来显示基于焦点控件的消息。为什么不直接使用所讨论控件的GotFocus事件呢?@GenericTypeTea-很好。除了显示消息之外,我还需要对留下的控件的值进行一些处理。可以在GotFocus中完成,但会有点尴尬。