Home > other >  Drawing rectangles on picture box
Drawing rectangles on picture box

Time:08-10

So I'm trying to automate drawing a bunch of rectangles over an image. I've mostly figured out how to draw them, but the problem I'm running into is that I only seem to be able to get them to actually be drawn when I interact with the picture box.

namespace myGUI
{
  public partial class formPicture : Form
  {
    public formPicture()
    {
      InitializeComponent();

      pbImage.Image = Image.FromFile(@"../../Images/myImage.bmp");

      // Doesn't Work
      var g = pbImage.CreateGraphics();
      g.DrawRectangle(new Pen(Color.Red, 5), 500, 200, 20, 20);
    }

    private void formPicture_Shown(object sender, EventArgs e)
    {
      // Doesn't Work
      var g = pbImage.CreateGraphics();
      g.DrawRectangle(new Pen(Color.Red, 5), 500, 200, 20, 20);
    }

    private void pbImage_Click(object sender, EventArgs e)
    {
      // Works
      var g = pbImage.CreateGraphics();
      g.DrawRectangle(new Pen(Color.Red, 5), 500, 200, 20, 20);
    }
  }
}

The pbImage_Click() call successfully draws the rectangle on my picture box. The other two instances of trying to draw the rectangle don't seem to result in anything.

I have no idea why it would work in one case, but not the others? I've tried invalidating the graphics, that didn't work. I've tried adding it to the Paint event, that didn't work. I've tried adding it to the validated event, the visible event, the loaded event, pretty much any other event that I can think of such that once the GUI was active it might actually result in the rectangle being drawn.

The only time it seems to work is Click or MouseClick (I haven't tried other interactive events, such as MouseUp or MouseDown, but I presume those would work as well. Besides, the whole point is that I want it to show up automatically.)

CodePudding user response:

NEVER call CreateGraphics. If you want to draw on a control, handle the Paint event of that control and use the e.Graphics property provided. If the drawing needs to change, store the data that describes the drawing in one or more fields, then read those fields in the Paint event handler. If you need to force the drawing to change, modify those fields and then call Invalidate on the control. Ideally, pass an argument to that Invalidate method that describes the smallest area that has or might have changed. Here's one I and a friend prepared earlier.

Note that WinForms controls are painted and repainted quite often, so any drawing done outside the Paint event handler is likely to be wiped. That's exactly what's happening in the cases that you say are not working. The drawing is being done but is then wiped. By doing your drawing in the Paint event handler, you ensure that it is reinstated every time it is wiped, so it appears permanent.

  • Related