Разработка пользовательского интерфейса на основе технологии Windows Presentation Foundation - страница 17
Обратить внимание на интересную особенность полученного макета. Поскольку для одного из полей ввода мы задали свойство MinWidth, ширина полей ввода не может стать меньше значения этого свойства, но может увеличиваться, если ее минимального размера недостаточно для отображения введенного текста. При этом будет пропорционально увеличиваться и ширина компонента Grid, и ширина всего окна, причем кнопки будут по-прежнему выровнены по правой границе.
Недочет. При первом отображении диалогового окна в нем отсутствует активный компонент (т. е. элемент, имеющий фокус). В дальнейшем при закрытии и последующем открытии диалогового окна в нем будет активным тот компонент, который имел фокус в момент закрытия. Оба эти обстоятельства затрудняют работу с диалоговым окном. В частности, при повторном открытии диалогового окна его активным компонентом с большой долей вероятности будет кнопка «ОК» или «Отмена» (если предыдущее закрытие окна было выполнено путем нажатия на эту кнопку), что потребует от пользователя лишних действий для перехода к тому полю ввода, которое он хочет изменить. Этот недочет будет исправлен в п. 2.6.
2.6. Установка активного компонента окна. Особенности работы с фокусом в библиотеке WPF
В классе Window2 добавьте в метод Window_IsVisibleChanged следующий оператор:
Результат. При первом открытии диалогового окна фокус ввода принимает компонент textBox1. Этот же компонент оказывается активным и при последующих открытиях диалогового окна, независимо от того, какой компонент окна был активным в момент его закрытия. Таким образом, диалоговое окно всегда отображается в одном и том же начальном состоянии. Подобное поведение желательно обеспечивать для любых диалоговых окон.
Комментарии
1. Отметим, что указанное действие по установке фокуса происходит при скрытии окна. В этом можно убедиться, если добавить перед оператором установки фокуса условие:
В то же время, если использовать вариант
то фокус на первом поле ввода при последующих открытиях окна устанавливаться не будет.
Подобное странное поведение объясняется двумя такими же странными особенностями библиотеки WPF. Во-первых, метод Focus обеспечивает установку фокуса для указанного компонента только в случае, если в момент вызова метода окно отображается на экране (хотя более естественным было бы реализовать метод таким образом, чтобы он в любом случае сохранял информацию об установке фокуса и учитывал ее при отображении окна). Заметим, что метод Focus возвращает логическое значение, которое равно true, если вызов метода действительно обеспечил успешную установку фокуса на данном элементе.
Во-вторых, при установке свойства IsVisible равным true событие IsVisibleChanged наступает до того момента, как окно появится на экране, и наоборот, при установке свойства IsVisible равным false событие IsVisibleChanged выполняется, когда окно еще отображается на экране. Подобное поведение тоже представляется нелогичным, поскольку не позволяет связать некоторые действия (например, установку фокуса) с тем моментом, когда окно в очередной раз отображается на экране.
Тем не менее при первом отображении диалогового окна поле ввода textBox1 все же получает фокус, хотя это, казалось бы, противоречит сказанному выше. Это связано с особенностями реализации механизма настройки фокуса в WPF: если в окне еще не установлен активный компонент