Frage

Ich habe eine Bild-box-set to AutoSize, so dass das Bild zwingt Sie, zu wachsen, um das Bild in voller Größe.

Das Bildfeld ist in einem panel mit autoScroll = true, so dass Bildlaufleisten angezeigt werden, wenn das Bild größer ist als das panel.

Wie kann ich programmgesteuert scrollen Sie das Bedienfeld an, wenn der Benutzer auf die drags auf das Bild, damit der Neupositionierung des Bildes.

Ich habe versucht, verwendet das MouseMove-Ereignis, das erfassen, die letzten X-und Y-Position der Maus, um zu berechnen, wie viel die Maus bewegt hat, und justiert die Vertikalen und Horizontalen Scroll-Werte der Platte.

Der bewegt sich das Bild um, aber es springt ganz über dem Platz, und Schriftrollen unvorhersehbar.

Wie kann ich das erreichen?

Hier ist, was ich in meiner Maus Ereignisse...

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (dragging)
    {
        if (e.Button == MouseButtons.Left)
        {
            // move the image inverse to direction dragged
            int horizontalChange = (e.X - startingX) * -1;  
            int newHorizontalPos = panel1.HorizontalScroll.Value + horizontalChange;

            if (newHorizontalPos < panel1.HorizontalScroll.Minimum)
            {
                newHorizontalPos = panel1.HorizontalScroll.Minimum;
                horizontalChange = 0;
            }

            if (newHorizontalPos > panel1.HorizontalScroll.Maximum)
            {
                newHorizontalPos = panel1.HorizontalScroll.Maximum;
                horizontalChange = 0;
            }

            panel1.HorizontalScroll.Value = newHorizontalPos;

            int verticalChange = (e.Y - startingY);
            // move the image inverse to direction dragged
            int newverticalPos = panel1.VerticalScroll.Value + verticalChange * -1;  

            if (newverticalPos < panel1.VerticalScroll.Minimum)
            {
                newverticalPos = panel1.VerticalScroll.Minimum;
                verticalChange = 0;
            }

            if (newverticalPos > panel1.VerticalScroll.Maximum)
            {
                newverticalPos = panel1.VerticalScroll.Maximum;
                verticalChange = 0;
            }

            panel1.VerticalScroll.Value = newverticalPos;
        }
    }

    startingX = e.X;
    startingY = e.Y;
}

Ist meine Logik falsch oder ist mein Verständnis von der Platte-scrolling-Funktionalität falsch?

War es hilfreich?

Lösung

Ich glaube, Ihr Instinkt ist richtig, doch dein Fehler ist, zu versuchen, passen Sie die Bildlaufleisten, anstatt sich die PictureBox innerhalb des scrollbaren panel.

Sollten Sie abfangen, MouseMove und passen Sie die PictureBox ' s Location-Eigenschaft, die durch die Bewegung der Maus delta — die Bildlaufleisten automatisch aktualisiert, um das Bild der neuen Lage in es.

Aktualisieren Sie Ihr code würde folgendermaßen Aussehen tho folgenden (ungetestet):

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (dragging)
    {
        if (e.Button == MouseButtons.Left)
        {
            int horizontalChange = (e.X - startingX) * -1;  // move the image inverse to direction dragged

            int verticalChange = (e.Y - startingY);

            pictureBox1.Left += horizontalChange;
            pictureBox1.Top += verticalChange;
        }
    }

    startingX = e.X;
    startingY = e.Y;
}

(Außerdem würde ich geneigt sein, zu Protokollierung der Start-Maus und PictureBox-Standorten an den start des ziehen und aktualisieren Sie Sie relativ zu dieser Ausgangslage auf jedem MouseMove-Ereignis eher als inkrementelle änderungen wie der code oben (und Ihr ursprünglicher code funktioniert).Der Grund dafür ist, dass, wenn es sind alle unerwarteten Werte, aus welchem Grund auch immer, dann wird dies nur dazu führen, dass ein vorübergehender Effekt — die nächste positive Ereignis wird, sich selbst zu korrigieren.)

Andere Tipps

Es springt, weil der Akt der das Panel Scrollen wird die Mausposition durch den Scroll-Betrag abwerfen. Sie können die „echte“ Mausposition (relative von der oberen linken Ecke des Fensters) wie diese:

  Point realPos = new Point(e.X + panel1.AutoScrollPosition.X,
    e.Y + panel1.AutoScrollPosition.Y);

vorausgesetzt, das Bildfeld Lage der Immobilie ist (0, 0). Der beste Weg, um das Panel zu bewegen ist seine Autoscrollposition Eigenschaft festzulegen.

können Sie die AutoScrollPosition Panel-Set in Mousemove-Ereignis. Getestet und funktioniert gut.

panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top