Как использовать ScrollableControl с параметром AutoScroll, установленным в false

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

Я пытался использовать AutoScroll, но это не дало удовлетворительных результатов. Когда я устанавливал AutoScrollPosition и AutoScrollMinSize один за другим (в любом порядке ), это приводило к принудительному отрисовке и вызывало дрожание при каждом изменении масштаба. Я предполагаю, что это произошло потому, что он вызывал обновление, а не недействительность, когда я изменял оба свойства.

Теперь я вручную устанавливаю свойства HorizontalScroll и VerticalScroll с AutoScroll, установленным на false таким образом, каждый раз, когда изменяется уровень масштабирования или размер клиента.:

int canvasWidth = (int)Math.Ceiling(Image.Width * Zoom) + PageMargins.Horizontal;
int canvasHeight = (int)Math.Ceiling(Image.Height * Zoom) + PageMargins.Vertical;

HorizontalScroll.Maximum = canvasWidth;
HorizontalScroll.LargeChange = ClientSize.Width;

VerticalScroll.Maximum = canvasHeight;
VerticalScroll.LargeChange = ClientSize.Height;

if (canvasWidth > ClientSize.Width)
{
    HorizontalScroll.Visible = true;
}
else
{
    HorizontalScroll.Visible = false;
    HorizontalScroll.Value = 0;
}

if (canvasHeight > ClientSize.Height)
{
    VerticalScroll.Visible = true;
}
else
{
    VerticalScroll.Visible = false;
    VerticalScroll.Value = 0;
}

int focusX = (int)Math.Floor((FocusPoint.X * Zoom) + PageMargins.Left);
int focusY = (int)Math.Floor((FocusPoint.Y * Zoom) + PageMargins.Top);

focusX = focusX - ClientSize.Width / 2;
focusY = focusY - ClientSize.Height / 2;

if (focusX < 0)
    focusX = 0;
if (focusX > canvasWidth - ClientSize.Width)
    focusX = canvasWidth - ClientSize.Width;

if (focusY < 0)
    focusY = 0;
if (focusY > canvasHeight - ClientSize.Height)
    focusY = canvasHeight - ClientSize.Height;

if (HorizontalScroll.Visible)
    HorizontalScroll.Value = focusX;

if (VerticalScroll.Visible)
    VerticalScroll.Value = focusY;

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

Что не работает, так это полосы прокрутки. Если пользователь попытается выполнить прокрутку вручную, щелкнув любую полосу прокрутки, они оба будут возвращаться к 0. Я не устанавливаю их больше нигде в своем коде.Я попытался написать следующее в методе OnScroll ():

if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
{
    VerticalScroll.Value = se.NewValue;
}
else
{
    HorizontalScroll.Value = se.NewValue;
}

Invalidate();

, но это вызывает очень неустойчивое поведение, включая пролистывание и прокрутку за пределы.

Как мне написать код для OnScroll? Я попробовал base.OnScroll, но он ничего не сделал, пока для AutoScroll установлено значение false.

7
задан Trevor Elliott 23 April 2012 в 18:47
поделиться