如何提供根据鼠标滚轮上下调整到图片框形状的尺寸调整功能

锡普

活跃的成员
已加入
2019年3月6日
留言内容
27
地点
班加罗尔
编程经验
Beginner
你好
1.我有一个画框,并且画了一个矩形。
2.如果用户单击形状,则可以基于存储的坐标知道是否单击了形状。
3.现在,我想通过使用鼠标滚轮事件(缩放形状)在形状上提供调整大小功能,它可以向上或向下。
4.我已经注册了一个活动

图片框鼠标滚轮事件:
Private void PictureBoxImage_MouseWheel(object sender, MouseEventArgs e)
{
    
}

5.我将创建一个Matrix对象,但是在Scale方法上要传递什么值, 标度方法链接?我能从你那里得到一些想法吗?
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,497
地点
悉尼,澳大利亚
编程经验
10+
这是您想要的东西:
C#:
private float scale = 1.0F;

private void Form1_Load(object sender, EventArgs e)
{
    pictureBox1.MouseWheel += PictureBox1_MouseWheel;
    pictureBox1.Paint += PictureBox1_Paint;
}

private void PictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
    // Scale in 0.1 increments down to a minimum of 0.1.
    scale = Math.Max(scale + Math.Sign(e.Delta) * 0.1F, 0.1F);

    pictureBox1.Refresh();
}

private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
    var matrix = new Matrix();

    matrix.Scale(scale, scale, MatrixOrder.Append);

    e.Graphics.Transform = matrix;
    e.Graphics.DrawRectangle(Pens.Black, 10, 10, 50, 100);
}
在X和Y方向上使用相同的比例值,因此保留了宽高比。用户每拨动一个档位,比例尺就会增加0.1。同样,每降低一个陷波,它就会减少0.1,最低为0.1。
 

锡普

活跃的成员
已加入
2019年3月6日
留言内容
27
地点
班加罗尔
编程经验
Beginner
这是您想要的东西:
C#:
private float scale = 1.0F;

private void Form1_Load(object sender, EventArgs e)
{
    pictureBox1.MouseWheel += PictureBox1_MouseWheel;
    pictureBox1.Paint += PictureBox1_Paint;
}

private void PictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
    // Scale in 0.1 increments down to a minimum of 0.1.
    scale = Math.Max(scale + Math.Sign(e.Delta) * 0.1F, 0.1F);

    pictureBox1.Refresh();
}

private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
    var matrix = new Matrix();

    matrix.Scale(scale, scale, MatrixOrder.Append);

    e.Graphics.Transform = matrix;
    e.Graphics.DrawRectangle(Pens.Black, 10, 10, 50, 100);
}
在X和Y方向上使用相同的比例值,因此保留了宽高比。用户每拨动一个档位,比例尺就会增加0.1。同样,每降低一个陷波,它就会减少0.1,最低为0.1。
兄弟,可以缩放而不移动它吗?
意思是:在缩放并平移到图片框上的其他位置之后,我们将缩放以定型,我们可以在原始位置上缩放,现在感觉就像缩放并平移一样吗?
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,497
地点
悉尼,澳大利亚
编程经验
10+
您不仅要缩放矩形,还要缩放整个画布。该代码在原点下方10像素处和右侧10像素处绘制顶部,左上角,因此这些值也将被缩放。如果不希望缩放画布时矩形的左上角移动,则必须在原点处绘制它,这意味着您需要将原点平移到希望将左上角移到的位置画。在下面的代码中,将原点平移了10个像素,向右平移了10个像素,并在原点处绘制了拐角,而不是将角向下降低了10个像素,向右绘制了10个像素。您必须在缩放后执行转换,我认为这是违反直觉的,但这就是它的工作方式。
C#:
private float scale = 1.0F;

private void Form1_Load(object sender, EventArgs e)
{
    pictureBox1.MouseWheel += PictureBox1_MouseWheel;
    pictureBox1.Paint += PictureBox1_Paint;
}

private void PictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
    // Scale in 0.1 increments down to a minimum of 0.1.
    scale = Math.Max(scale + Math.Sign(e.Delta) * 0.1F, 0.1F);

    pictureBox1.Refresh();
}

private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
    var matrix = new Matrix();

    matrix.Scale(scale, scale, MatrixOrder.Append);
    matrix.Translate(10.0F, 10.0F, MatrixOrder.Append);

    e.Graphics.Transform = matrix;
    e.Graphics.DrawRectangle(Pens.Black, 0, 0, 50, 100);
}
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,497
地点
悉尼,澳大利亚
编程经验
10+
请注意,上面的代码仍会缩放整个画布,因此,如果您绘制多个形状,其他形状仍然会移动。如果要能够缩放多个形状而不移动,则需要在绘制每个形状之前平移原点,然后在原点绘制每个形状,例如
C#:
private float scale = 1.0F;

private void Form1_Load(object sender, EventArgs e)
{
    pictureBox1.MouseWheel += PictureBox1_MouseWheel;
    pictureBox1.Paint += PictureBox1_Paint;
}

private void PictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
    // Scale in 0.1 increments down to a minimum of 0.1.
    scale = Math.Max(scale + Math.Sign(e.Delta) * 0.1F, 0.1F);

    pictureBox1.Refresh();
}

private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
    var matrix = new Matrix();

    matrix.Scale(scale, scale, MatrixOrder.Append);
    matrix.Translate(10.0F, 10.0F, MatrixOrder.Append);

    e.Graphics.Transform = matrix;
    e.Graphics.DrawRectangle(Pens.Black, 0, 0, 50, 100);

    matrix.Translate(200.0F, 0.0F, MatrixOrder.Append);

    e.Graphics.Transform = matrix;
    e.Graphics.DrawRectangle(Pens.Black, 0, 0, 50, 100);
}
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,497
地点
悉尼,澳大利亚
编程经验
10+
If you wanted to be able to scale multiple shapes separately then you'd have to store separate scale values for each shape and only modify the right one in the MouseWheel event handler, then create a new Matrix with the appropriate translation and scale before drawing each shape.
 

锡普

活跃的成员
已加入
2019年3月6日
留言内容
27
地点
班加罗尔
编程经验
Beginner
If you wanted to be able to scale multiple shapes separately then you'd have to store separate scale values for each shape and only modify the right one in the MouseWheel event handler, then create a new Matrix with the appropriate translation and scale before drawing each shape.

我包含了要投影的代码,但我的picturebox.Refresh();出现了一些问题。我可以在图片框上找到额外的刷新,请帮帮我。
代码:
我的刷新代码中的问题:
GraphicsPath path=new GraphicsPath();
private float scale=1.0F;
private bool ActiveWheel=false;
public Form1()
{
    path.AddRectangle(new Rectangle(0,0,50,100));
}
private void PictureBox1_Paint(object sender,PaintEventArgs e)
{
    if(ActiveWheel)
    {
        ActiveWheel=false;
        ScaleRectangle(e);
        pictureBox1.Invalidate();
    }
else
{
   e.Graphics.DrawPath(Pens.Red,path);
}
}
private void ScaleRectangle(PaintEventArgs e)
{
    var matrix=new Matrix();
    matrix.Scale(scale,scale,MatrixOrder.Append);
    path.Transform(matrix);
    e.Graphics.DrawPath(Pens.Blue,path);
}

请运行代码:进行5次鼠标滚轮上升和2次鼠标滚轮下降,它不会减小(按比例缩小),但是形状像按鼠标滚轮向上一样按比例放大,这是什么问题?兄弟。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,497
地点
悉尼,澳大利亚
编程经验
10+
Don't call Invalidate in the Paint event handler. That's the method you call if you want to cause that event to be raised. If you cause the event to be raised each time it's raised, it will never stop being raised. Look at the code I provided. Do I ever do that? I call Refresh in the MouseWheel event handler, so that's where you would call Invalidate. Refresh calls Invalidate and then also calls Update, which causes the Paint event to be raised immediately rather than waiting until other queued events have been processed.
 

锡普

活跃的成员
已加入
2019年3月6日
留言内容
27
地点
班加罗尔
编程经验
Beginner
Don't call Invalidate in the Paint event handler. That's the method you call if you want to cause that event to be raised. If you cause the event to be raised each time it's raised, it will never stop being raised. Look at the code I provided. Do I ever do that? I call Refresh in the MouseWheel event handler, so that's where you would call Invalidate. Refresh calls Invalidate and then also calls Update, which causes the Paint event to be raised immediately rather than waiting until other queued events have been processed.
我将代码从pictureBox1.Invalidate()更改为pictureBox1.Refresh(),但问题仍然存在。

code:
GraphicsPath path=new GraphicsPath();
private float scale=1.0F;
private bool ActiveWheel=false;
public Form1()
{
    path.AddRectangle(new Rectangle(0,0,50,100));
}
private void PictureBox1_Paint(object sender,PaintEventArgs e)
{
    if(ActiveWheel)
    {
        ActiveWheel=false;
        ScaleRectangle(e);
     //I removed the pictureBox1.Invalidate() from here also.
    }
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);
}
 
最佳 底部