Убедитесь, что вложенный дочерний элемент управления виден
У меня есть служебная программа, которую я вызываю, когда проверка ввода пользователя в диалоге завершается неудачно. Он устанавливает фокус на нарушающее управление, издает звуковые сигналы и отображает соответствующее сообщение для пользователя. Это работает хорошо, пока нарушающий контроль не скрыт. Теперь я должен приспособить это к ситуации, когда соответствующие элементы управления являются дочерними элементами неких складных групповых блоков (возможно, даже вложенных), и я должен убедиться, что поля "предков" раскрыты перед вызовом SetFocus.
Теперь у меня есть несколько возможностей:
- Внедрить знания о сворачиваемом компоненте в процедуру сообщения об ошибках. Я хотел бы избежать этого, так как рутина должна быть довольно общей.
- Передайте обратный вызов, который может быть вызван до (или вместо) SetFocus. Это подвержено ошибкам, потому что нужно помнить, чтобы передать обратный вызов во всех соответствующих местах.
- Моим любимым решением, вероятно, было бы событие (или переопределяемый метод) (возможно, в TWinControl), которое сообщает элементу управления контейнера "пожалуйста, убедитесь, что вы и ваши дочерние элементы управления видимы", но я не знаю такой вещи.
Есть идеи, как я могу справиться с этой ситуацией?
3 ответа
На мой взгляд, лучшим решением была бы отдельная подпрограмма, которая собирает знания обо всех элементах управления контейнером, позволяя подпрограмме проверки диалога оставаться общей и в то же время достаточно сфокусированной, чтобы ее можно было легко протестировать и поддерживать. Что-то вроде:
procedure ForceControlVisible(C: TControl);
begin
// Recursive code
if Assigned(C.Parent) then ForceControlVisible(C.Parent);
// Code specific to each container control class
if C is TTabSheet then
begin
// Code that makes sure "C" is the active page in the PageControl
// goes here. We already know the PageControl itself is visible because
// of the recursive call.
end
else if C is TYourCollapsibleBox then
begin
// Code that handles your specific collapsible boxes goes here
end
end;
Методы в стиле ООП, основанные на виртуальных методах или реализации интерфейсов, были бы более элегантными, но требуют доступа к исходному коду всех элементов управления, которые вы хотите использовать: даже если у вас есть доступ ко всем необходимым источникам, предпочтительно не вводить любые изменения, потому что это затрудняет обновление этих элементов управления (вам нужно будет повторно представить ваши изменения после получения новых файлов от поставщика).
- Определите интерфейс с методом, который называется что-то вроде:
EnsureVisible
, - Реализуйте его для всех ваших компонентов (вам может потребоваться получить собственные версии некоторых из этих компонентов). Это позволяет различным элементам управления вести себя совершенно по-разному.
- Когда элемент управления должен убедиться, что он виден, он гуляет с родителями и звонит
EnsureVisible
если интерфейс реализован.
Если вам не нравятся интерфейсы, сделайте это с помощью специального сообщения Windows, но вы поймете основную идею.
Каждый компонент знает свой Parent
, Вы можете пройти вверх по списку, чтобы сделать каждого родителя видимым.