首页 > 解决方案 > 如何在C#中缩放GraphicsPath对象上的矩形或形状时修复图片框刷新时鼠标滚轮上下之间的延迟?

问题描述

1.当用户在图片框上上下鼠标时,我正在尝试缩放一个矩形。
2.在向上移动 5 次鼠标滚轮后,如果向下移动鼠标滚轮,矩形仍然保持放大(扩大)。
3.有什么解决办法吗?

GraphicsPath path=new GraphicsPath();
private float scale=1.0F;
private bool ActiveWheel=false;
public Form1()
{
    path.AddRectangle(new Rectangle(10,10,50,100));
}
private void PictureBox1_Paint(object sender,PaintEventArgs e)
{
    if(ActiveWheel)
    {
        ActiveWheel=false;
        ScaleRectangle(e);

    }
else
{
   e.Graphics.DrawPath(Pens.Red,path);
}

}
private void PictureBox1_MouseWheel(object sender,MouseEventArgs e)
{
    ActiveWheel=true;
    scale=Math.Max(scale+Math.Sign(e.Delta)*0.1F,0.1F);
    pictureBox1.Refresh();
}
}
private void ScaleRectangle(PaintEventArgs e)
{
    var matrix=new Matrix();
    matrix.Scale(scale,scale,MatrixOrder.Append);
    path.Transform(matrix);
    e.Graphics.DrawPath(Pens.Blue,path);
}

任何解决方案或想法如何在鼠标滚轮向上和鼠标滚轮向下之间没有延迟的情况下突然缩小或放大形状(请参阅 2. 如果想实际查看 o/p)。

标签: c#.netgdi+

解决方案


只需在 MouseWheel() 事件中调整比例值,然后在 Paint() 事件中 ScaleTransform() GRAPHICS 表面(不是路径本身)并绘制:

public partial class Form1 : Form
{

    private GraphicsPath path = new GraphicsPath();
    private float scale = 1.0F;

    public Form1()
    {
        InitializeComponent();
        path.AddRectangle(new Rectangle(10, 10, 50, 100));
        pictureBox1.MouseWheel += PictureBox1_MouseWheel;
        pictureBox1.Paint += pictureBox1_Paint;
    }

    private void PictureBox1_MouseWheel(object sender, MouseEventArgs e)
    {
        scale = Math.Max(scale + Math.Sign(e.Delta) * 0.1F, 0.1F);
        pictureBox1.Invalidate();
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.ScaleTransform(scale, scale);
        e.Graphics.DrawPath(Pens.Red, path);
    }

}

- - 编辑 - -

它完全缩放,你能告诉我如何只缩放图形路径对象和顶部,左侧必须固定,这意味着不缩放顶部,左侧点?

在这种情况下,平移到矩形的左上角,缩放,然后平移回原点。现在画出你的 UNCHANGED 矩形:

    private void PictureBox1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.TranslateTransform(10, 10);
        e.Graphics.ScaleTransform(scale, scale);
        e.Graphics.TranslateTransform(-10, -10);
        e.Graphics.DrawPath(Pens.Red, path);
    }

如果您有其他元素在不同的位置和/或比例上绘制,那么您可以在之前和之后重置图形表面(每个“元素”可以做相同类型的事情来定位自己和缩放自己):

    private void PictureBox1_Paint(object sender, PaintEventArgs e)
    {

        // possibly other drawing operations

        e.Graphics.ResetTransform();
        e.Graphics.TranslateTransform(10, 10);
        e.Graphics.ScaleTransform(scale, scale);
        e.Graphics.TranslateTransform(-10, -10);
        e.Graphics.DrawPath(Pens.Red, path);
        e.Graphics.ResetTransform();

        // possibly other drawing operations

    }

这种方法很好,因为它保留了有关矩形的原始信息;这种变化只是视觉上的。


推荐阅读