Что предпочтительный путь состоит в том, чтобы найти сфокусированным управлением в приложении WinForms?

Ключевое слово extern информирует компилятор о том, что функция или переменная имеет внешнюю связь - другими словами, она видна из файлов, отличных от тех, в которых она определена. В этом смысле ключевое слово static имеет противоположный смысл. Немного странно ставить extern во время определения, поскольку никакие другие файлы не будут иметь видимость определения (или это приведет к нескольким определениям). Обычно вы помещаете extern в объявление в какой-то момент с внешней видимостью (например, файл заголовка) и помещаете определение в другое место.

63
задан Milan Gardian 12 January 2009 в 13:46
поделиться

5 ответов

Если у Вас уже есть другие вызовы к Windows API, нет никакого вреда в использовании решения Peters. Но я понимаю Ваше беспокойство об этом и склонялся бы к аналогичному решению как Ваши, использующий только технические возможности Платформы. В конце концов, различие в производительности (если существует один) не должно быть значительным.

я проявил бы не рекурсивный подход:

public static Control FindFocusedControl(Control control)
{
    var container = control as IContainerControl;
    while (container != null)
    {
        control = container.ActiveControl;
        container = control as IContainerControl;
    }
    return control;
}
65
ответ дан Hinek 7 November 2019 в 12:40
поделиться

При выполнении до конца ActiveControl рекурсивно, он не берет Вас к листовому управлению, которое фокусируется?

2
ответ дан sliderhouserules 7 November 2019 в 12:40
поделиться

После поиска Интернета я нашел следующий Windows Forms FAQ

George Shepherd, который.Net библиотеки платформы не предоставляют Вам API для запросов для сфокусированного Управления. Необходимо вызвать окна API, чтобы сделать так:

[C#]

public class MyForm : Form
{
          [DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.Winapi)]
          internal static extern IntPtr GetFocus();

          private Control GetFocusedControl()
          {
               Control focusedControl = null;
               // To get hold of the focused control:
               IntPtr focusedHandle = GetFocus();
               if(focusedHandle != IntPtr.Zero)
                    // Note that if the focused Control is not a .Net control, then this will return null.
                    focusedControl = Control.FromHandle(focusedHandle);
               return focusedControl;
          }
} 
26
ответ дан Xn0vv3r 7 November 2019 в 12:40
поделиться

Решение Hinek мне подходит, за исключением того, что это ContainerControl , а не ControlContainer. (На случай, если вы почесали голову из-за этой красной волнистой линии.)

    public static Control FindFocusedControl(Control control)
    {
        ContainerControl container = control as ContainerControl;
        while (container != null)
        {
            control = container.ActiveControl;
            container = control as ContainerControl;
        }
        return control;
    }
8
ответ дан Nate Cook 24 November 2019 в 15:24
поделиться

ActiveControl в форме или контейнере будет возвращать активный элемент управления этой сущности, независимо от того, насколько глубоко он может быть вложен в другие контейнеры.

В вашем примере, если TextBox имеет Фокус: затем: для Form, TableLayoutPanel и FlowLayoutPanel: свойство ActiveControl всех из них будет TextBox!

Некоторые, но не все, «настоящие» типы ContainerControl ... например, Form и UserControl ... раскрывают ключевые события (в случае формы: только если Form.KeyPreview == true можно использовать).

Другие элементы управления, которые по своей конструкции содержат другие элементы управления, такие как TableLayOutPanel, GroupBox, Panel, FlowLayoutPanel и т. Д., Относятся к не типу ContainerControl и не предоставляют KeyEvents. , которого нет в самой Форме ... обычного неконтейнерного Элемент управления вложен на несколько произвольных уровней глубоко ... вы можете использовать некоторые из идей в ответ: но код можно значительно упростить.

Обычные элементы управления, элементы управления контейнерами, элементы управления пользователями и т. д. (но не формы!) все имеют свойство «Контейнер», к которому вы можете получить доступ, чтобы получить их непосредственный контейнер, но убедитесь, что у вас есть последний Контейнер в их пути наследования, не являющийся формой, требует некоторого кода для "обхода" дерева наследования, которое демонстрируется здесь.

Вы также можете проверить свойство HasChildren элемента управления, которое обычно полезен при решении проблем Focus, ActiveControl и Select в WinForms. Здесь может быть полезно изучить разницу между Select и Focus,

20
ответ дан 24 November 2019 в 15:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: