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