J-P
J-P

Reputation: 403

Panning a drawing from a panel in C#

I have a drawing application that I use Graphic object to draw a rectangle and circles and some lines. The app has the capability of zooming, but I'm trying to get Panning working but couldn't find the best solution.

public partial class Form1 : Form
{
    protected Point clickPosition;
    protected Point scrollPosition;
    protected Point lastPosition;
    public Form1()
    {
        InitializeComponent();
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
        AutoScroll = true;
        AutoScrollMinSize = new Size(0, 0);
    }
    float zoom = 100f;
    private void panel1_Paint(object sender, PaintEventArgs e)
    {

        Graphics g = e.Graphics;
        g.ScaleTransform(zoom, zoom);
        g.SmoothingMode = SmoothingMode.AntiAlias;

        // some demo drawing:
        Rectangle rect = panel1.ClientRectangle;
        g.DrawEllipse(Pens.Firebrick, rect);
        using (Pen pen = new Pen(Color.DarkBlue, 4f)) 
            g.DrawLine(pen, 22, 22, 88, 88);
    }

    private void trackBar1_Scroll(object sender, EventArgs e)
    {
        zoom = trackBar1.Value / 10f;
        panel1.Invalidate();
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        clickPosition.X = e.X;
        clickPosition.Y = e.Y;
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        Cursor = Cursors.Default;
        lastPosition.X = AutoScrollPosition.X;
        lastPosition.Y = AutoScrollPosition.Y;
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            Cursor = Cursors.Hand;
            scrollPosition.X = clickPosition.X - e.X - lastPosition.X;
            scrollPosition.Y = clickPosition.Y - e.Y - lastPosition.Y;
            AutoScrollPosition = scrollPosition;
            panel1.Invalidate();
        }
    }

    private void Viewer_MouseDown(object sender, MouseEventArgs e)
    {
        OnMouseDown(e);
    }

    private void Viewer_MouseMove(object sender, MouseEventArgs e)
    {
        OnMouseMove(e);
    }

    private void Viewer_MouseUp(object sender, MouseEventArgs e)
    {
        OnMouseUp(e);
    }
}

this what I have so far, the code missing 2 things one is Using AutoScrollMinSize to update the min size and AutoScrollPosition to get the latest position, the problem is both can be used with DrawImage and Images and I'm not sure in my case how to get it work with line drawing and circles. Also for some reason my AutoScrollPosition always 0 for x and y. Any Ideas, or is there another way to create the pan effect

Upvotes: 0

Views: 2545

Answers (1)

TaW
TaW

Reputation: 54433

You can use the very same trick for panning as for zooming: Pan the Graphics object used for drawing!

Simply add one (or for vertical panning as well two) numbers, say offSetX and offsetY to your application. You may controls it with a Trackbar or a NumericUpDown or in any other way..

Now add this line that translates (pans) everything the Graphics object draws, before the ScaleTransform:

g.TranslateTransform(offSetX , offSetY);

This will move everything for so many pixels to the right or left and up or down..

Note that this includes everything the Graphics object draws, including all images it draws.

But this will not move a BackgroundImage if you have one.. To move those as well you should use two Panels: A panelFrame with AutoSize on and a larger panelCanvas which is nested in the frame panel and gets moved around inside it by using the scrollbars..

Upvotes: 3

Related Questions