Как удержать элементы управления в Scroll Box от перехода в фокус?
У меня есть TScrollBox
который прокручивается вертикально, а горизонтальная полоса прокрутки отключена. Внутри этого поля прокрутки находится одна большая панель, выровненная по верху, а ее высота динамически рассчитывается на основе ее содержимого. Его содержимое состоит из двух панелей, одна выровнена по левому краю, а другая выровнена по клиенту, с разделителем между ними. Внутри каждой из этих двух панелей находится ряд выбранных пользователем панелей, выровненных по верху, которые также могут динамически изменять размеры, таким образом, увеличивая / уменьшая высоту основной панели внутри поля прокрутки.
procedure TfrmDashboard.ResizePanels;
var
X: Integer;
H1, H2: Integer;
H: Integer;
begin
H1:= 0;
H2:= 0;
//Calculate height of left panel
for X := 0 to p1.ControlCount-1 do
H1:= H1 + p1.Controls[X].Height;
//Calculate height of right panel
for X := 0 to p2.ControlCount-1 do
H2:= H2 + p2.Controls[X].Height;
//Check which panel is larger
H:= H1;
if H2 > H then
H:= H2;
//Adjust scrolling height
pMain.Height:= H + 10;
SB.VertScrollBar.Range:= pMain.Height;
SB.VertScrollBar.Size:= pMain.Height;
end;
В то же время, большинство из этих небольших подпанелей контента также имеют элементы управления, которые получают фокус и должны позволять фокусироваться. Все отлично работает с прокруткой в настоящее время.
Проблема возникает, когда пользователь нажимает на один из таких фокусируемых элементов управления в поле прокрутки. Если этот элемент управления оказался частично скрытым (верхняя часть элемента управления простирается выше верхней части прокручиваемой позиции), весь блок прокрутки поднимается вверх, чтобы расположить этот элемент управления в верхней части блока прокрутки.
Это похоже на "функцию", но функцию, которую я хотел бы отключить. Это довольно раздражает в этой ситуации. Как предотвратить прокрутку поля прокрутки, когда один из его детей получает фокус?
1 ответ
Это поведение по умолчанию для TScrollBox, и нет свойства, чтобы отключить эту функцию.
Но вы можете изменить это поведение, создав подкласс TScrollBox и использовать вместо этого этот новый класс:
TModifiedScrollBox=class(TScrollBox)
protected
procedure AutoScrollInView(AControl:TControl); override;
end;
procedure TModifiedScrollBox.AutoScrollInView(AControl:TControl);
begin
// empty body
end;
Недостатком этого кода является то, что AutoScrollInView перестает работать, если вы используете его в своем собственном коде. Но если вам все еще нужен этот метод, вы можете создать дополнительный метод для его сохранения:
TModifiedScrollBox=class(TScrollBox)
protected
procedure AutoScrollInView(AControl:TControl); override;
procedure AutoScrollInViewSave(AControl:TControl);
end;
procedure TModifiedScrollBox.AutoScrollInViewSave(AControl:TControl);
begin
// forward to base implementation
inherited AutoScrollInView(AControl);
end;
И затем в вашем коде вы должны заменить все вызовы AutoScrollInView на AutoScrollInViewSave для этого нового класса.
PS При каждом обращении к новому элементу управления TCustomForm вызывает AutoScrollInView для всех родителей этого целевого элемента управления.