什么是preferred地找到集中控制在WinForms应用程序?集中控制、应用程序、preferred、WinForms

2023-09-02 01:20:01 作者:丿glorious灬永恒

什么是地发现,目前接收的WinForms用户(键盘)输入控制preferred /最简单的方法是什么?

What is the preferred/easiest way to find the control that is currently receiving user (keyboard) input in WinForms?

到目前为止,我想出了以下内容:

So far I have come up with the following:

public static Control FindFocusedControl(Control control)
{
    var container = control as ContainerControl;
    return (null != container
        ? FindFocusedControl(container.ActiveControl)
        : control);
}

这是一种形式,这可以简称为(在.NET 3.5 +这甚至可以被定义为窗体上的扩展方法) -

From a form, this can be called simply as (in .NET 3.5+ this could even be defined as an extension method on the form) -

var focused = FindFocusedControl(this);

这是适当的?

Is this appropriate?

有没有办法,我应该使用,而不是一个内置的方法?

Is there a built-in method that I should be using instead?

请注意,要ACTIVECONTROL一个电话是不够的层次时使用。试想一下:

Note that a single call to ActiveControl is not enough when hierarchies are used. Imagine:

Form
    TableLayoutPanel
        FlowLayoutPanel
            TextBox (focused)

(formInstance).ActiveControl将返回参考TableLayoutPanel中,而不是文本框(因为ACTIVECONTROL似乎只在返回直接激活的孩子在控件树,而我在寻找叶控制)。

(formInstance).ActiveControl will return reference to TableLayoutPanel, not the TextBox (because ActiveControl seems to only be returning immediate active child in the control tree, while I'm looking for the leaf control).

推荐答案

如果您有其他调用Windows API已经,有使用彼得斯的解决方案没有坏处。但我理解你对此的担忧,并倾向于类似的解决方案是你的,只使用该框架的功能。毕竟,性能差异(如果有的话)不应显著

If you have other calls to the Windows API already, there's no harm in using Peters solution. But I understand your worries about it and would tend to a similar solution as yours, using only the Framework functionalities. After all, the performance difference (if there is one) shouldn't be significant.

我会采取一种非递归的方式:

I would take a non recursive approach:

public static Control FindFocusedControl(Control control)
{
    var container = control as IContainerControl;
    while (container != null)
    {
        control = container.ActiveControl;
        container = control as IContainerControl;
    }
    return control;
}