C# 有没有一种方法可以捕获ContainesFocus更改的时间?

C# 有没有一种方法可以捕获ContainesFocus更改的时间?,c#,winforms,events,C#,Winforms,Events,我需要能够确定控件(特别是windows窗体)上的何时包含焦点更改。覆盖OnGotFocus不是答案。当我将表单放到前台时,ContainsFocus为true,Focused为false。那么,ContainsFocus是否有一个OnGotFocus等价物呢?或者其他方法?解决这个问题的一种方法是使用计时器。这绝对是蛮力,但它完成了任务: private Timer m_checkContainsFocusTimer = new Timer(); private bool m_contains

我需要能够确定
控件(特别是windows窗体)上的
何时包含焦点更改。覆盖OnGotFocus
不是答案。当我将表单放到前台时,
ContainsFocus
为true,
Focused
为false。那么,
ContainsFocus
是否有一个
OnGotFocus
等价物呢?或者其他方法?

解决这个问题的一种方法是使用计时器。这绝对是蛮力,但它完成了任务:

private Timer m_checkContainsFocusTimer = new Timer();
private bool m_containsFocus = true;

m_checkContainsFocusTimer.Interval = 1000; // every second is good enough
m_checkContainsFocusTimer.Tick += new EventHandler(CheckContainsFocusTimer_Tick);
m_checkContainsFocusTimer.Start();

private void CheckContainsFocusTimer_Tick(object sender, EventArgs e)
{
    if (!m_containsFocus && ContainsFocus)
        OnAppGotFocus();

    m_containsFocus = ContainsFocus;
}

但是有更简单的方法吗?

解决这个问题的一个方法是使用计时器。这绝对是蛮力,但它完成了任务:

private Timer m_checkContainsFocusTimer = new Timer();
private bool m_containsFocus = true;

m_checkContainsFocusTimer.Interval = 1000; // every second is good enough
m_checkContainsFocusTimer.Tick += new EventHandler(CheckContainsFocusTimer_Tick);
m_checkContainsFocusTimer.Start();

private void CheckContainsFocusTimer_Tick(object sender, EventArgs e)
{
    if (!m_containsFocus && ContainsFocus)
        OnAppGotFocus();

    m_containsFocus = ContainsFocus;
}

但是有更简单的方法吗?

处理GotFocus和LostFocus事件应该可以做到这一点

还有一件事需要注意。。。SDK对ContainsFocus属性作了如下说明:

您可以使用此属性来确定 无论是控件还是 其中包含的控件具有 输入焦点。确定 控件具有焦点,而与 其任何子控件是否具有 聚焦,使用聚焦属性

编辑:

处理GotFocus事件时,您可能仍需要检查Focus/ContainsFocus属性,具体取决于控件层次结构的设置方式

如果控件或其任何子控件具有焦点,则ContainsFocus将为true。
仅当特定控件本身具有焦点时,无论其子控件如何,焦点才为真。

处理GotFocus和LostFocus事件应该可以做到这一点

还有一件事需要注意。。。SDK对ContainsFocus属性作了如下说明:

您可以使用此属性来确定 无论是控件还是 其中包含的控件具有 输入焦点。确定 控件具有焦点,而与 其任何子控件是否具有 聚焦,使用聚焦属性

编辑:

处理GotFocus事件时,您可能仍需要检查Focus/ContainsFocus属性,具体取决于控件层次结构的设置方式

如果控件或其任何子控件具有焦点,则ContainsFocus将为true。
仅当特定控件本身具有焦点时,无论其子控件如何,焦点才为真。

注意:如果您具有子控件,则会触发子控件的GotFocus事件。否则将调用窗体的OnGotFocus

如果我正确理解了这个问题,那么这应该是可行的:

    bool lastNotificationWasGotFocus = false;

    protected override void OnControlAdded(ControlEventArgs e)
    {
        SubscribeEvents(e.Control);
        base.OnControlAdded(e);
    }

    protected override void OnControlRemoved(ControlEventArgs e)
    {
        UnsubscribeEvents(e.Control);
        base.OnControlRemoved(e);
    }

    private void SubscribeEvents(Control control)
    {
        control.GotFocus += new EventHandler(control_GotFocus);
        control.LostFocus += new EventHandler(control_LostFocus);
        control.ControlAdded += new ControlEventHandler(control_ControlAdded);
        control.ControlRemoved += new ControlEventHandler(control_ControlRemoved);

        foreach (Control innerControl in control.Controls)
        {
            SubscribeEvents(innerControl);
        }
    }

    private void UnsubscribeEvents(Control control)
    {
        control.GotFocus -= new EventHandler(control_GotFocus);
        control.LostFocus -= new EventHandler(control_LostFocus);
        control.ControlAdded -= new ControlEventHandler(control_ControlAdded);
        control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved);

        foreach (Control innerControl in control.Controls)
        {
            UnsubscribeEvents(innerControl);
        }
    }

    private void control_ControlAdded(object sender, ControlEventArgs e)
    {
        SubscribeEvents(e.Control);
    }

    private void control_ControlRemoved(object sender, ControlEventArgs e)
    {
        UnsubscribeEvents(e.Control);
    }

    protected override void OnGotFocus(EventArgs e)
    {
        CheckContainsFocus();
        base.OnGotFocus(e);
    }

    protected override void OnLostFocus(EventArgs e)
    {
        CheckLostFocus();
        base.OnLostFocus(e);
    }

    private void control_GotFocus(object sender, EventArgs e)
    {
        CheckContainsFocus();
    }

    private void control_LostFocus(object sender, EventArgs e)
    {
        CheckLostFocus();
    }

    private void CheckContainsFocus()
    {
        if (lastNotificationWasGotFocus == false)
        {
            lastNotificationWasGotFocus = true;
            OnContainsFocus();
        }
    }

    private void CheckLostFocus()
    {
        if (ContainsFocus == false)
        {
            lastNotificationWasGotFocus = false;
            OnLostFocus();
        }
    }

    private void OnContainsFocus()
    {
        Console.WriteLine("I have the power of focus!");
    }

    private void OnLostFocus()
    {
        Console.WriteLine("I lost my power...");
    }

注意:如果您有子控件,则会激发子控件的GotFocus事件。否则将调用窗体的OnGotFocus

如果我正确理解了这个问题,那么这应该是可行的:

    bool lastNotificationWasGotFocus = false;

    protected override void OnControlAdded(ControlEventArgs e)
    {
        SubscribeEvents(e.Control);
        base.OnControlAdded(e);
    }

    protected override void OnControlRemoved(ControlEventArgs e)
    {
        UnsubscribeEvents(e.Control);
        base.OnControlRemoved(e);
    }

    private void SubscribeEvents(Control control)
    {
        control.GotFocus += new EventHandler(control_GotFocus);
        control.LostFocus += new EventHandler(control_LostFocus);
        control.ControlAdded += new ControlEventHandler(control_ControlAdded);
        control.ControlRemoved += new ControlEventHandler(control_ControlRemoved);

        foreach (Control innerControl in control.Controls)
        {
            SubscribeEvents(innerControl);
        }
    }

    private void UnsubscribeEvents(Control control)
    {
        control.GotFocus -= new EventHandler(control_GotFocus);
        control.LostFocus -= new EventHandler(control_LostFocus);
        control.ControlAdded -= new ControlEventHandler(control_ControlAdded);
        control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved);

        foreach (Control innerControl in control.Controls)
        {
            UnsubscribeEvents(innerControl);
        }
    }

    private void control_ControlAdded(object sender, ControlEventArgs e)
    {
        SubscribeEvents(e.Control);
    }

    private void control_ControlRemoved(object sender, ControlEventArgs e)
    {
        UnsubscribeEvents(e.Control);
    }

    protected override void OnGotFocus(EventArgs e)
    {
        CheckContainsFocus();
        base.OnGotFocus(e);
    }

    protected override void OnLostFocus(EventArgs e)
    {
        CheckLostFocus();
        base.OnLostFocus(e);
    }

    private void control_GotFocus(object sender, EventArgs e)
    {
        CheckContainsFocus();
    }

    private void control_LostFocus(object sender, EventArgs e)
    {
        CheckLostFocus();
    }

    private void CheckContainsFocus()
    {
        if (lastNotificationWasGotFocus == false)
        {
            lastNotificationWasGotFocus = true;
            OnContainsFocus();
        }
    }

    private void CheckLostFocus()
    {
        if (ContainsFocus == false)
        {
            lastNotificationWasGotFocus = false;
            OnLostFocus();
        }
    }

    private void OnContainsFocus()
    {
        Console.WriteLine("I have the power of focus!");
    }

    private void OnLostFocus()
    {
        Console.WriteLine("I lost my power...");
    }

抱歉,但正如我在问题中所说,GotFocus不适用于此。@MikeHall是对的。GotFocus不在父控件上激发,它的子控件之一获得焦点。因此,问题仍然是当父级包含焦点更改时如何获取事件。不幸的是,这个问题的答案只适用于通过控件添加的控件。添加,如果孩子们自己添加了控件,则不适用……抱歉,但正如我在问题中所说,GotFocus不适用于此。@MikeHall是对的。GotFocus不在父控件上激发,它的子控件之一获得焦点。因此,问题仍然是当父级包含焦点更改时如何获取事件。不幸的是,这个问题的答案只适用于通过控件添加的控件。添加,如果孩子们自己添加了控件,则不起作用…我知道这应该起作用,但当窗体被带到前台时,甚至不会调用OnGotFocus。因此,不会调用checkContainsFous()。所以你也有同样的问题(如果您有子控件,则会激发子控件的GotFocus事件。否则会调用窗体的OnGotFocus。只需检查“private void OnContainsFocus()”是否为是否被调用。我做了,一个it正在工作。我尝试了它,它工作了。对于窗体上的控件,从来没有调用过覆盖OnGotFocus,但确实调用了控件。\u GotFocus。就是这样。谢谢。我知道这应该行得通,但当窗体被带到前台时,OnGotFocus甚至没有被调用。因此,请选中ContainesFocusus()将不会被调用。因此您将面临相同的问题。:(如果您有子控件,则会激发子控件的GotFocus事件。否则将调用窗体的OnGotFocus。只需检查“private void OnContainsFocus()”是否为是否被调用。我做了,一个it正在工作。我尝试了它,它工作了。表单上的控件从未调用过override OnGotFocus,但控件GotFocus确实被调用过。就是这样。谢谢。等了12年才有人需要这个提示?我在这里!等了12年才有人需要这个提示?我在这里!