Mam niestandardową kontrolę, która powiększa niestandardowe płótno dokumentu.Jak używać ScrollableControl z AutoScroll ustawionym na false
Próbowałem używać AutoScroll, ale nie dawało satysfakcjonujących wyników. Gdybym ustawił AutoScrollPosition i AutoScrollMinSize z powrotem na tył (w dowolnej kolejności), wymuszałby malowanie i powodował drgania za każdym razem, gdy zmienia się zoom. Zakładam, że było tak, ponieważ wywołał aktualizację, a nie unieważnił, gdy zmodyfikowałem obie właściwości.
Jestem teraz ręczne ustawienie właściwości HorizontalScroll i VerticalScroll z AutoScroll ustawiona na false jak więc za każdym razem poziom powiększenia lub zmiany rozmiaru klient:
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;
W tym przypadku FocusPoint jest Struktura PointF, która przechowuje współrzędne mapy bitowej, na której użytkownik jest skupiony (na przykład, kiedy kółko myszy do powiększenia, koncentrują się na bieżącej lokalizacji myszy w tym czasie). Ta funkcja działa w większości przypadków.
Co nie działa to paski przewijania. Jeśli użytkownik spróbuje ręcznie przewinąć, klikając dowolny pasek przewijania, oba powracają do wartości 0. Nie umieszczam ich nigdzie indziej w moim kodzie. Próbowałem pisząc co następuje w metodzie OnScroll():
if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
{
VerticalScroll.Value = se.NewValue;
}
else
{
HorizontalScroll.Value = se.NewValue;
}
Invalidate();
Ale to powoduje pewne bardzo złe zachowanie w tym wylać i przewijanie poza granicami.
Jak mam napisać kod do OnScroll? Próbowałem już base.OnScroll, ale nic nie zrobił, podczas gdy AutoScroll jest ustawiony na false.
Myślę, że dobrze się spisałeś po raz pierwszy. Najpierw ustaw AutoScrollMinSize, a następnie wywołaj AutoScrollPosition. Użyj podwójnie buforowanego panelu, aby kontrolować migotanie. – LarsTech
Moja kontrola była podwójnie buforowana. Nigdy nie migotała, z wyjątkiem sytuacji, gdy jednocześnie zmieniałem zarówno AutoScrollMinSize, jak i AutoScrollPosition. –