Как предотвратить автоматическую прокрутку контейнера скроллинга при фокусе частично скрытого дочернего элемента в Delphi
При работе с компонентом TScrollBox в Delphi может возникнуть ситуация, когда при фокусировке на частично скрытом дочернем элементе контейнер скроллинга автоматически прокручивается, чтобы показать этот элемент. Это может быть раздражающим поведением, которое хочется отключить. В данной статье мы рассмотрим, как предотвратить это поведение.
Описание проблемы
У вас есть TScrollBox, который прокручивается вертикально, а горизонтальная панель скроллинга отключена. Внутри этого контейнера скроллинга находится единственная большая панель, выровненная по верху, высота которой dynamiquecки рассчитывается на основе ее содержимого. Содержимое состоит из двух панелей (одна выровнена по левому краю, а другая - по клиенту) с разделителем посередине. Внутри каждой из этих двух панелей находятся серии пользовательских панелей, выровненных по верху, которые также могут динамически менять свой размер, тем самым увеличивая/уменьшая высоту основной панели внутри контейнера скроллинга.
При этом многие из этих меньших под-панелей содержимого также имеют контроли, которые получают фокус и должны позволять получать фокус. В настоящее время все работает нормально со скроллингом.
Проблема возникает, когда пользователь щелкает по одному из таких фокусируемых контролов внутри контейнера скроллинга. Если этот контроль частично скрыт (верхняя часть контрола находится выше текущей позиции прокрутки), то весь контейнер скроллинга подпрыгивает, чтобы позиционировать этот контроль вверху контейнера скроллинга.
Это похоже на "фичу", но "фичу", которую вы хотели бы отключить. Это довольно раздражающее поведение в данной ситуации. Как предотвратить подпрыгивание контейнера скроллинга, когда один из его детей получает фокус?
Решение проблемы
Это стандартное поведение TScrollBox, и нет свойства, которое можно было бы отключить. Однако вы можете изменить это поведение, создав подкласс TScrollBox и используя его вместо стандартного:
TModifiedScrollBox = class(TScrollBox)
protected
procedure AutoScrollInView(AControl: TControl); override;
end;
procedure TModifiedScrollBox.AutoScrollInView(AControl: TControl);
begin
// Пустой метод
end;
Минусом этого кода является то, что AutoScrollInView перестает работать, если вы используете его в своем коде. Но если вам все еще нужен этот метод, вы можете создать дополнительный метод для "сохранения" его:
TModifiedScrollBox = class(TScrollBox)
protected
procedure AutoScrollInView(AControl: TControl); override;
procedure AutoScrollInViewSave(AControl: TControl);
end;
procedure TModifiedScrollBox.AutoScrollInViewSave(AControl: TControl);
begin
// Передать вызов базовому методу
inherited AutoScrollInView(AControl);
end;
И затем в вашем коде вы должны заменить все вызовы AutoScrollInView на AutoScrollInViewSave для этого нового класса.
Вывод
Мы рассмотрели проблему автоматической прокрутки контейнера скроллинга при фокусировке на частично скрытом дочернем элементе в Delphi и предложили решение, основанное на создании подкласса TScrollBox. Это позволяет предотвратить нежелательное поведение контейнера скроллинга и сохранить работоспособность метода AutoScrollInView, если он вам нужен.
Как предотвратить автоматическую прокрутку контейнера скроллинга при фокусировке частично скрытого дочернего элемента в Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS