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

锡普

活跃成员
已加入
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,563
地点
悉尼,澳大利亚
编程经验
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,563
地点
悉尼,澳大利亚
编程经验
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,563
地点
悉尼,澳大利亚
编程经验
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,563
地点
悉尼,澳大利亚
编程经验
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,563
地点
悉尼,澳大利亚
编程经验
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);
}
 
最佳 底部