Resizing drawlines on a paint event

坚强是说给别人听的谎言 提交于 2020-01-07 09:22:25

问题


I've seen few questions about this problem, I tried every solution but none of them worked for my case. My code is working; this image shows what happens when I click on Draw button. I need to zoom on that drawing.Is it possible to code something like autocad feature "zoom/extent"?

Pen myPen = new Pen(Color.Black);
int centerpointx, centerpointy;
private void pictureBoxDraw_Paint(object sender, PaintEventArgs e)
    {
        centerpointx = pictureBoxDraw.Size.Width/2;
        centerpointy = pictureBoxDraw.Size.Height/2;

        myPen.Width = 2;
        if (binary > 0)
        {
            var sizecrestgeo = 40;
            var distancearraycrestgeo = new float[sizecrestgeo];
            var elevationarraycrestgeo = new float[sizecrestgeo];
            for (int i = 0; i < sizecrestgeo; i++)
            {
                distancearraycrestgeo[i] = float.Parse(dataGridViewCrestGeo.Rows[i].Cells[0].Value.ToString());
                elevationarraycrestgeo[i] = float.Parse(dataGridViewCrestGeo.Rows[i].Cells[1].Value.ToString())*-1;

            }
            for (int i=0; i < sizecrestgeo-1; i++)
            {
            e.Graphics.DrawLine(myPen, distancearraycrestgeo[i]+centerpointx, elevationarraycrestgeo[i]+centerpointy, distancearraycrestgeo[i + 1]+centerpointx, elevationarraycrestgeo[i + 1]+centerpointy);
            }
        }
        else
        {
        }
    }

    private void buttonDraw_Click_1(object sender, EventArgs e)
    {
        if (Hd > 0.0001)
        {
            binary = 1;
            pictureBoxDraw.Invalidate();
        }
        else
        {
            MessageBox.Show("No data to draw, perform analysis first.");
        }

    }

    private void buttoncleardraw_Click(object sender, EventArgs e)
    {
        binary = 0;
        pictureBoxDraw.Invalidate();
    }
}

回答1:


Graphics.ScaleTransform() is how you can zoom. Try using something like this inside your paint event handler:

e.Graphics.ScaleTransform(2.0F, 2.0F);



回答2:


This is not so hard, provided you know all the puzzle pieces.

Let's start with the obvious one:

  • You can scale the Graphics object to create zoomed graphics with ScaleTransform.

As I mentioned, this will include the widths of pens, font sizes and also any images you draw (though not the hatches of a HatchBrush).

You also asked about keeping the drawing 'centered'. This is a non-obvious concept: Just what is the center of your drawing surface??

When zooming (just like rotating) you always need to know the center point of the zoom (or the rotation.) By default this is the origin (0,0). I chose the center of the Panel. You may want to pick some other point..

Once you do you can move the origin of the graphics viewport to this point with TranslateTransform.

Once you have achieved all this you almost certainly will want to allow scrolling.

To do so you have two options:

  • You can keep AutoScroll = false and nest the canvas control inside another control, usually a Panel, which has AutoScroll = true; next make the canvas control big enough to always hold your drawing and you're done.

  • Or you can turn on AutoScroll for the canvas control and also set a large enough AutoScrollMinSize. If you then add the current scrolling position to the translation you are also done. Let's see this solution in action:

This is the code in the Paint event:

Size sz = panel3.ClientSize;
Point center = new Point(sz.Width / 2, sz.Height / 2);
Graphics g = e.Graphics;

// center point for testing only!
g.DrawEllipse(Pens.Orange, center.X - 3, center.Y - 3, 6, 6);

// you determine the value of the zooming!
float zoom = (trackBar1.Value+1) / 3f;

// move the scrolled center to the origon
g.TranslateTransform(center.X + panel3.AutoScrollPosition.X, 
                        center.Y + panel3.AutoScrollPosition.Y);
// scale the graphics
g.ScaleTransform(zoom, zoom);

// draw some stuff..
using(Pen pen = new Pen(Color.Yellow, 0.1f))
for (int i = -100; i < 100; i+= 10)
        g.DrawEllipse(Pens.Yellow, i-22,i-22,44,44);

A few notes:

  • I draw an orange circle in the center to show this point is invariant.
  • My coordinates go from the negative to the positive so you can see that this works nicely.
  • I draw with a tiny pen width; so the width of the drawing only changes once the resulting pen goes over 1 pixel. Anything draw will always be draw with 1 pxiel width, though.
  • I first translate and then scale so I don't have to calculate scaled poitions.
  • The only line in the TrackBar's Scroll event is to trigger the Paint event: panel3.Invalidate();

The only settings needed for the Panel are

 panel3.AutoScroll = true;
 panel3.AutoScrollMinSize = new Size(500, 500);  // use the size you want to allow!

However to avoid flicker it is highly recommended to use a DoubleBuffered control, maybe a Panel subclass like this:

class DrawPanel : Panel
{
    public DrawPanel()      { DoubleBuffered = true;  }
}

Update: Instead of a Panel, which is a Container control and not really meant to draw onto you can use a Picturebox or a Label (with Autosize=false); both have the DoubleBuffered property turned on out of the box and support drawing better than Panels do.



来源:https://stackoverflow.com/questions/44079331/resizing-drawlines-on-a-paint-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!