在绘画事件中调整绘图线的大小 [英] Resizing drawlines on a paint event

查看:128
本文介绍了在绘画事件中调整绘图线的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于此问题,我看到的问题很少,我尝试了每种解决方案,但没有一种适用于我的情况. 我的代码正在运行;此图像显示了当我单击绘制"按钮时发生的情况. 我需要放大该绘图.是否可以对诸如autocad功能缩放/范围"之类的代码进行编码?

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();
    }
}

推荐答案

如果您知道所有拼图,这并不难.

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

让我们从显而易见的一个开始:

Let's start with the obvious one:

  • 您可以缩放Graphics对象以使用ScaleTransform创建缩放的图形.
  • You can scale the Graphics object to create zoomed graphics with ScaleTransform.

正如我提到的,这将包括笔的宽度,字体大小以及您绘制的任何图像(尽管不是HatchBrush的阴影).

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??

缩放(就像旋转一样)时,您始终需要知道缩放(或旋转)的中心点.默认情况下,这是原点(0,0).我选择了Panel的中心.您可能还需要选择其他一点.

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..

一旦完成,您就可以使用TranslateTransform将图形视口的原点移动到这一点.

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.

为此,您有两个选择:

  • 您可以将AutoScroll = false嵌套画布控件保留在另一个控件内,通常是Panel,该控件具有AutoScroll = true;接下来,使画布控件足够大以始终保留您的图形,然后就完成了.

  • 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.

或者您可以打开AutoScroll进行画布控制,还可以设置足够大的AutoScrollMinSize.然后,如果您将当前滚动位置添加到翻译中,则也将完成.让我们看看这个解决方案的实际效果:

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:

这是Paint事件中的代码:

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);

一些注意事项:

  • 我在中心画了一个橙色的圆圈,以表明该点是不变.
  • 我的坐标从负数变为正数,因此您可以看到它很好地工作.
  • 我用很小的笔宽度画画;因此,一旦生成的笔超过1个像素,图形的宽度就只会改变.但是,任何绘制都将始终以1 pxiel的宽度绘制.
  • 我先翻译然后缩放,这样我就不必计算缩放的磅数.
  • TrackBarScroll事件中唯一的行是触发Paint事件:panel3.Invalidate();
  • 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();

Panel唯一需要的设置是

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

但是要避免忽悠,强烈建议使用DoubleBuffered控件,也许是这样的Panel子类:

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;  }
}


更新:可以使用PictureboxLabel(对于Autosize=false );都具有开箱即用的DoubleBuffered属性,并且比Panels更好地支持绘图.


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.

这篇关于在绘画事件中调整绘图线的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆