Сброс фокуса на элемент управления с наименьшим индексом табуляции

#vb.net #winforms

#vb.net #winforms

Вопрос:

У меня есть форма, которая используется повторно. То есть вместо того, чтобы каждый раз создавать новый экземпляр формы, форма остается скрытой и становится видимой при необходимости. (Дизайн, который я унаследовал; я полагаю, это была оптимизация производительности.)

Проблема: во второй раз, когда используется форма, фокус находится на кнопке OK или Cancel, начиная с первого использования формы.

Пользователь хочет, чтобы фокус начинался так, как это было при первом появлении формы — на элементе управления с наименьшим индексом вкладки.

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

Но таких форм много, и логика видимости находится в общем базовом классе.

Поэтому было бы разумнее сделать это правильно и указать форме сосредоточиться на своем первом (самом низком tabindex) элементе управления.

Есть ли простой способ сделать это?

(Я мог бы перебрать все элементы управления, но тогда мне нужно правильно обрабатывать вложенные элементы управления. Поскольку графический интерфейс должен делать это при первом отображении формы, я надеюсь, что есть какой-то метод, который я могу вызвать, который сделает это за меня.)

(Закодировано в VB.net , но ответ на C # был бы неплох.)

Комментарии:

1. ПРИМЕЧАНИЕ: Одно из решений, которое я придумал, — добавить настраиваемое поле в базовый класс. Каждый подкласс может установить для этого поля элемент управления, который должен быть выбран при открытии формы (или повторном отображении; снова становится видимым). Pro: не зависит от индексов вкладок, и иногда это полезно. Con: не зависит от индексов табуляции, а это дополнительная работа и обслуживание.

2. Второе решение, которое кажется немного неясным, заключается в том, чтобы базовый класс различал создание формы в первый раз и повторное использование формы. В первый раз я не уверен, в каком событии, ПОМНИТЕ, какой элемент управления стал активным. В последующие разы ВЫБЕРИТЕ (или установите ActiveControl) этот запоминаемый элемент управления.

Ответ №1:

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

Итак, что-то вроде этого:

 public void ShowAgain() {
    this.Show();
    this.SelectNextControl(this, true, true, true, true);
}
 

И учтите, что объект формы, который не виден, является довольно крупным ресурсоемким, использующим много ресурсов операционной системы для небольшого удобства. Конечно, вы также можете закрыть / удалить его и воссоздать при необходимости. YMMV.

Комментарии:

1. Похоже, в моей ситуации есть какая-то другая проблема, мешающая фокусировке. Использую ли я свой исходный код (просто показывает) или использую ваш код и / или код Джейкоба, form2, похоже, находится в странном состоянии: для моей простейшей form2 текстовое поле с кнопками OK и cancel, переход через них проходит через 3 состояния, но когда текстовое полеактивный, он по-прежнему не получает фокус клавиатуры: нет курсора и ничего не происходит при нажатии клавиши. Отлично работает при первом появлении; это происходит только при втором появлении.

2. (Хотя это требует изменения кода в каждой форме в этом большом приложении, я надеюсь в конечном итоге избавиться от всех форм. Я бы никогда не реализовал это таким образом. Это может быть «незначительная» ошибка, которая заставляет меня переписывать этот код. Помните, что эта плохо организованная кодовая база может злоупотреблять некоторыми формами для хранения данных, поэтому избегайте этого, если мне не нужно.)

3. Если я нажму на какое-либо другое окно, а затем вернусь к form2, фокус текстового поля волшебным образом начнет работать правильно. То же самое, если я переключаю Alt-Tab в другое приложение, а затем обратно.

4. Вы можете поместить этот код в обработчик событий для активированного события формы. Ваш пользователь будет ненавидеть вас.

5. Нет, я говорю, что это отлично работает при переключении между приложениями. Так что не нужно делать что-то особенное при активации. Alt-tabbing был просто случайным тестом, чтобы определить, что было странным в фокусе. Что странно, так это то, что он не работает, ПОКА я не сделаю что-то, что вызывает вторую активацию. Тем не менее, я попытался добавить это в Activated и убедился, что затем он попадает в точку останова. По-прежнему не работает до Alt-tab и обратно.

Ответ №2:

Вы можете попробовать установить свойство ActiveControl, прежде чем сделать форму видимой:

 _frm.ActiveControl = null;
 

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

Комментарии:

1. Согласно моему комментарию к ответу Ганса, в моем случае это не помогает, хотя, вероятно, это хорошее решение, как только я найду, что мешает фокусировке в моей конкретной ситуации.

2. Если я переключаю вкладку в другое приложение, а затем обратно, я вижу, что текстовое поле активно (а не кнопка отмены при первом использовании form2). Итак, это работает так, как рекламируется (если я могу определить, почему фокус клавиатуры находится в запутанном состоянии, когда form2 появляется при повторном отображении, пока я не нажму Alt-tab или не перейду к другой форме, а затем обратно).

3. ПРИМЕЧАНИЕ: Хотя я проверил Hans в качестве ответа, это решение работает одинаково хорошо.