C# 图形被覆盖

发布于 2024-09-14 18:23:32 字数 1083 浏览 4 评论 0原文

在 c# 中,我在 win 窗体上使用 PictureBox。

我正在尝试重新创建 MSPaint 以了解图形对象。这一切都工作得很好,除了当另一个窗口位于 PictureBox 顶部时,或者调整整个窗体的大小时,在另一个窗口下绘制的内容将被删除。

这是我正在使用的代码的缩小版本。

private Graphics _g;
private bool _bIsMouseDown = false;

private void picCanvas_MouseDown(object sender, MouseEventArgs e)
{
  if (!_bIsGraphicsSet) _g = picCanvas.CreateGraphics();
  _bIsMouseDown = true;
  DrawRectangle(e);
}

private void picCanvas_MouseMove(object sender, MouseEventArgs e)
{
  if (_bIsMouseDown) DrawRectangle(e);
}

private void picCanvas_MouseUp(object sender, MouseEventArgs e)
{
  _bIsMouseDown = false;
}

private void DrawRectangle(MouseEventArgs e)
{
    System.Drawing.Rectangle r = CreateRectangle(e);
    Pen pen = ChooseDrawColor();
    _g.DrawRectangle(pen, r);
}

private Rectangle CreateRectangle(MouseEventArgs e)
{
  int h = 10; 
  int w = 10; 
// there is code in here for multiple sized rectangles, 
//I know the math can be simplified for this example. 
          return new Rectangle(e.X - (w / 2), e.Y - (h / 2), w, h);
        }

任何想法将不胜感激。

In c# I am using a PictureBox on a win form.

I am trying to recreate MSPaint to learn about the Graphics Object. It all works fine and dandy except that when another window is on on top of the PictureBox, or the entire form is resized, what is drawn under the other window in there is removed.

Here is a scaled down version of the code I am working with.

private Graphics _g;
private bool _bIsMouseDown = false;

private void picCanvas_MouseDown(object sender, MouseEventArgs e)
{
  if (!_bIsGraphicsSet) _g = picCanvas.CreateGraphics();
  _bIsMouseDown = true;
  DrawRectangle(e);
}

private void picCanvas_MouseMove(object sender, MouseEventArgs e)
{
  if (_bIsMouseDown) DrawRectangle(e);
}

private void picCanvas_MouseUp(object sender, MouseEventArgs e)
{
  _bIsMouseDown = false;
}

private void DrawRectangle(MouseEventArgs e)
{
    System.Drawing.Rectangle r = CreateRectangle(e);
    Pen pen = ChooseDrawColor();
    _g.DrawRectangle(pen, r);
}

private Rectangle CreateRectangle(MouseEventArgs e)
{
  int h = 10; 
  int w = 10; 
// there is code in here for multiple sized rectangles, 
//I know the math can be simplified for this example. 
          return new Rectangle(e.X - (w / 2), e.Y - (h / 2), w, h);
        }

Any thoughts would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

秋心╮凉 2024-09-21 18:23:32

这是因为您不是在窗口上绘图,而是只是在窗口所在的屏幕上绘图。

您需要使用 Paint 事件来进行绘图。您需要以某种方式存储您绘制的内容,或者作为命令列表以便您可以重复它们,或者作为位图图像。

因此,当您想要绘制某些内容时,您可以将其添加到命令列表中或将其绘制在位图上,然后使控件无效,以便调用 Paint 事件。在 Paint 中,您甚至可以添加代码来执行实际绘图,即重复列表中的命令,或将位图绘制到控件上。

That is because you are not drawing on the window, you are just drawing on the screen where the window happens to be.

You need to use the Paint event to do the drawing. You need to store what you draw in some way, either as a list of commands so that you can repeat them, or as a bitmap image.

So, when you want to draw something, you add it to your list of commands or draw it on the bitmap, then you invalidate the control so that the Paint event is invoked. In the Paint even you add the code to do the actual drawing, i.e. repeat the commands in your list, or draw the bitmap onto the control.

不气馁 2024-09-21 18:23:32

您需要将所有绘图代码移至 Paint 事件处理程序。在鼠标事件处理程序中,只需设置一些反映新图像状态的变量,并使窗口无效。看一下这个示例: http://www.codeproject.com/KB/graphics /drawtools.aspx

You need to move all drawing code to the Paint event handler. In mouse event handlers, just set some variables reflecting new image state, and invalidate the window. Take a look at this sample: http://www.codeproject.com/KB/graphics/drawtools.aspx

梦里°也失望 2024-09-21 18:23:32

我认为您面临的是您的照片痘在其油漆事件中被重新油漆。

我通常采用的管理自定义绘画作业的方法是:将

  • 图片的一些抽象表示存储为类成员。对于你的情况,它可能是形状的集合、位图等。
  • 重写 OnPaint 方法(如果扩展控件)或 Paint 事件处理程序,并使用上面存储的数据重复绘图步骤。
  • 在应导致更新的事件(例如 picCanvas_MouseDown)中,对控件调用 Invalidate() 以强制其重新绘制。

由于调整大小事件会导致无效,因此您的绘制例程将被调用,并且图片将看起来保持不变。

I think what you are facing is that your picture pox gets repainted on its paint event.

The approach I usually take to managing custom paint jobs is this:

  • Store some abstract representation of your picture as a class member. I your case, it may be a collection of shapes, a bitmap, or so on.
  • Override the OnPaint method (if extending a control) or the Paint event handler, and repeat your drawing steps using the data you've stored above.
  • In events that should cause an update, such as picCanvas_MouseDown, call Invalidate() on the control to force it to repaint.

Because resize events cause invalidation, your paint routine will get called, and the picture will appear to remain unchanged.

心病无药医 2024-09-21 18:23:32

您可以创建一个图像来存储绘图。

private Bitmap _drawBuffer;

...

_drawBuffer = new Bitmap(pictureBox.Image);
_g = Graphics.FromImage(_drawBuffer));

...

private void DrawRectangle(MouseEventArgs e)
{
    System.Drawing.Rectangle r = CreateRectangle(e);
    Pen pen = ChooseDrawColor();
    _g.DrawRectangle(pen, r);
    pictureBox.Image = _drawBuffer;
}

这样做的好处是可以使用 Image.Save 函数保存图像。
您需要在调整大小时调整位图的大小。

You could create an image to store the drawing.

private Bitmap _drawBuffer;

...

_drawBuffer = new Bitmap(pictureBox.Image);
_g = Graphics.FromImage(_drawBuffer));

...

private void DrawRectangle(MouseEventArgs e)
{
    System.Drawing.Rectangle r = CreateRectangle(e);
    Pen pen = ChooseDrawColor();
    _g.DrawRectangle(pen, r);
    pictureBox.Image = _drawBuffer;
}

This comes with the plus side of being able to save the image using the Image.Save function.
You'll need to resize the bitmap on resize.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文