C# 在鼠标移动时绘制MS Paint用户定义的矩形
我现在正在用C#在面板上绘制一些形状。我在更新当前图形时遇到问题。换句话说,我不知道如何创建一个当前阶段(我将在其中绘制当前,比方说矩形)并在面板上绘制它。我可以在面板事件的C# 在鼠标移动时绘制MS Paint用户定义的矩形,c#,drawing,C#,Drawing,我现在正在用C#在面板上绘制一些形状。我在更新当前图形时遇到问题。换句话说,我不知道如何创建一个当前阶段(我将在其中绘制当前,比方说矩形)并在面板上绘制它。我可以在面板事件的鼠标上画一个矩形。但是,在面板上按下鼠标后,如何在鼠标移动事件上显示当前矩形???我不想使用使其无效。因为它会清除以前制作的所有面板图形。请帮助我在移动鼠标时显示当前的矩形形状,并仅在释放鼠标后在面板上绘制它 Pen p_white = new Pen(new SolidBrush(Color.White), pen_thi
鼠标上画一个矩形。但是,在面板上按下鼠标后,如何在鼠标移动
事件上显示当前矩形???我不想使用使其无效
。因为它会清除以前制作的所有面板图形。请帮助我在移动鼠标时显示当前的矩形形状,并仅在释放鼠标后在面板上绘制它
Pen p_white = new Pen(new SolidBrush(Color.White), pen_thickness);
int w1 = Math.Abs(starx - curx); int h1 = Math.Abs(stary - cury);
Rectangle rec_new = new Rectangle(starx, stary - h1, w1, h1);
gpath.Reset();
gpath.AddRectangle(rec_new);// code that adds Rectangle in MOUSE_MOVE EVENT
g.DrawPath(p, gpath);
// Drawing the rectangle on Mouse Release Event. g was already binded to Panel.CreateGraphics
可以使用Invalidate()调用绘制方法
你必须把你的画全部移到那里!所以这条线
g.DrawPath(p, gpath);
进入绘画活动,如下所示:
e.Graphics.DrawPath(p, gpath);
因为您正在构建一个GraphicsPath,所以这是一个小小的更改。如果像创建更多图形一样构建图形,则必须在那里绘制所有图形
不能像在纸上那样在面板上重复绘制来构建图形;您必须以某种方式存储绘制动作。这听起来很乏味,但在这里你真的只需要移动一行
并且:随着您的进步,它将为您提供无限撤销、缩放等机会。请参阅以下说明:
Windows窗体控件不支持真正的透明度。这个
透明Windows窗体控件的背景由其
家长
不幸的是,这意味着我们不能用简单的方法做到这一点——将某种透明图像控件置于另一个控件之上。WinForms不能做到这一点
我使用的一种方法是在“前景”缓冲区内进行所有临时绘制(选择、未完成的绘制等),并根据需要使用背景图像控件的Paint
事件绘制临时对象
给定包含图像的PaintBox
控件,可以根据需要使用Paint
事件绘制前景缓冲区,并提供完全透明选项
public partial class Form1 : Form
{
public Bitmap Foreground;
public Form1()
{
InitializeComponent();
// Create foreground buffer same size as picture box
Foreground = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
// Draw a blue ellipse in the foreground buffer for something to see
using (var g = Graphics.FromImage(Foreground))
{
g.Clear(Color.Transparent);
g.DrawEllipse(Pens.Blue, 10, 10, 300, 100);
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(Foreground, 0, 0);
}
}
假设你的图片框里有东西,这会在上面画一个蓝色椭圆
每当您想要更改覆盖的前景图像时,都需要确保重新绘制PaintBox
控件。使用Invalidate
方法告诉Windows控件需要重新绘制
还有一些代码:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
e.Handled = true;
// draw foreground to background
using (var g = Graphics.FromImage(pictureBox1.Image))
g.DrawImage(Foreground, 0, 0);
// clear foreground
using (var g = Graphics.FromImage(Foreground))
g.Clear(Color.Transparent);
}
else if (e.KeyCode == Keys.Space)
{
e.SuppressKeyPress = true;
e.Handled = true;
// a random number source - probably better at form level
var rnd = new Random();
// draw a new random ellipse
using (var g = Graphics.FromImage(Foreground))
{
g.Clear(Color.Transparent);
g.DrawEllipse(Pens.Red, 0, 0, 30 + rnd.Next(500), 30 + rnd.Next(500));
}
// tell Windows to redraw the paintBox to show new foreground image
pictureBox1.Invalidate();
}
}
按Enter
将前景缓冲区提交到PaintBox
中的图像,按Space
在前景缓冲区中生成一个随机的新红色椭圆
同样的基本技术可以用于各种各样的事情,比如将图像粘贴到特定位置(粘贴到前景缓冲区中并在其中移动,然后在完成后将前景复制到背景之上)、显示选择对象等。你能把问题说得更清楚吗,,,,你想在哪里显示你的绘图,你想在哪里绘制..我想在面板上绘制我的矩形,像MS Paint一样,我在鼠标向下移动事件中获得起点,然后当我移动鼠标时,我的矩形会像MS Paint一样自动更改其大小,然后只有在鼠标释放后才绘制(保存)。谢谢,这很有效,但是另一个问题出现了,我画的矩形缩小了,并且改变了它的坐标。为什么?我知道当a()失效时就会发生这种情况;被称为,但不是。失效只是使油漆发生。因此,路径中的坐标现在指的是不同的东西。如果没有MouseDown、-Up、-Move和Paint的代码,我们不知道为什么……但我可以猜测:一些事件可能涉及到面板,其他事件涉及到表单,是吗?确保所有参考面板,使其坐标表示相同!每个控件都有一个绘画、鼠标等事件!形式也是如此。(这是一个控件)不,现在我不在面板上画画,我在PictureBox上画画,我还有与我的PictureBox事件相关的鼠标按下、鼠标移动、鼠标向上。我正确地绘制了前景图像,从鼠标的下点到鼠标的当前点,移动它可以完美地绘制矩形,向上缩放,向下缩放。但在我释放鼠标后,鼠标移动事件发生了。因此,我的矩形向下缩放并向上移动,从我释放鼠标的点即矩形端点向左移动。这个问题是否由背景图像引起??我将默认的背景作为白纸图片,并将背景和图片的大小设置为相同的谢谢,这是可行的,但出现了另一个问题,我绘制的矩形缩小,并更改其坐标。为什么?我知道当a()失效时就会发生这种情况;被称为此pictureBox1\u Paint
,此Form1\u KeyDown
混合了它所指的控件,因此坐标将表示不同的内容;要么让所有事情发生在小组的事件中,要么纠正小组的提议@user3505681如果正在绘制的图像以任何方式进行变换(缩放、转换、缩放等),则需要在绘制代码中执行相同的变换。我使用一个PictureBox来保存图像,无需缩放或其他操作,在一个面板内处理所需的滚动。