У меня есть настраиваемый элемент управления, который масштабирует нарисованный на заказ холст документа.
Я пытался использовать 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.