ContainsFocus更改时有没有办法捕获?

时间:2008-12-05 21:18:11

标签: c# winforms events

我需要能够确定ContainsFocus(特别是Windows窗体)上Control的更改时间。覆盖OnGotFocus不是答案。当我将表单带到前台时,ContainsFocus为真,Focused为假。那么OnGotFocus是否有ContainsFocus等价物?或者其他任何方式?

3 个答案:

答案 0 :(得分:2)

注意:如果您有子控件,则会触发子控件的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...");
    }

答案 1 :(得分:0)

解决此问题的一种方法是使用Timer。这绝对是蛮力,但它完成了工作:

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;
}

但有更简单的方法吗?

答案 2 :(得分:0)

处理GotFocus和LostFocus事件应该这样做。

需要注意的另一件事...... SDK说明了ContainsFocus属性:

  

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

编辑:

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

如果控件或其任何子项具有焦点,则ContainsFocus将为true。 只有当具体控制本身具有焦点时,焦点才会成立,无论其子女如何。