我现在正在使用C#在PANEL上绘制一些形状。我有更新当前图形的问题。换句话说,我不知道如何创建一个当前阶段(我将绘制当前阶段,让我们说矩形)并在Panel上绘制它。我可以在Panel的Mouse_down
事件上绘制一个矩形。但是如何在面板上按下鼠标后,在Mouse_move
事件上显示当前的矩形?我不想使用Invalidate
。因为它清除了之前制作的所有面板图。帮助我显示当MOUSE被移动时当前的矩形形状,并且仅在鼠标释放后在面板上绘制它。
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
答案 0 :(得分:0)
您 使用Invalidate()来调用Paint方法。
你必须在那里移动全部你的画作!所以这一行
g.DrawPath(p, gpath);
像这样进入Paint事件:
e.Graphics.DrawPath(p, gpath);
由于您正在构建GraphicsPath,因此这是一个小改动。如果你像创建更多的GraphicsPath一样构建你的绘图,那么它们都必须在那里绘制。
您不能像在纸上那样在面板上反复绘图来建立图纸;你必须以某种方式存储绘制动作。这听起来很乏味但在这里你真的只需要移动一行。
而且:随着你的进步,它将为你提供无限的撤销,缩放等机会。
答案 1 :(得分:0)
请参阅MSDN中的此说明:
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
会在前台缓冲区中生成一个随机的新红色椭圆。
相同的基本技术可用于各种事物,例如将图像粘贴到特定位置(粘贴到前景缓冲区中并在前台缓冲区中移动,然后在完成时将前景复制到背景上),显示选择对象等。