tags:

views:

47

answers:

3

Hi everyone,

I am trying to create this simple application in c#: when the user double clicks on specific location in the form, a little circle will be drawn. By one click, if the current location is marked by a circle - the circle will be removed.

I am trying to do this by simply register the MouseDoubleClick and MouseClick events, and to draw the circle from a .bmp file the following way:

private void MouseDoubleClick (object sender, MouseEventArgs e)
{
    Graphics g = this.CreateGraphics();
    Bitmap myImage = (Bitmap)Bitmap.FromFile("Circle.bmp");
    g.DrawImage(myImage, e.X, e.Y);
}

My problem is that I dont know how to make the circle unvisible when the user clicks its location: I know how to check if the selected location contains a circle (by managing a list of all the locations containig circles...), but I dont know how exactly to delete it.

Another question: should I call the method this.CreateGraphics() everytime the user double-clicks a location, as I wrote in my code snippet, or should I call it once on initialization?

+2  A: 

My personal preference is to put my images in instances of the Picturebox class. Reason being, I can simply call each Picturebox's Hide() function (or set 'Visible` to false).

What you're doing is drawing directly onto the window's client area, which technically isn't wrong but normally should be done in the form's Paint handler. If at some point you decide you don't want your circle to be visible anymore, you can call the form's Invalidate() method which triggers the Paint event. There, you explicitly do not draw your circle, and so to the user, the circle disappears.

The nice thing about a Picturebox is that it's persistent - you put your image into it and optionally draw on that image, but you only need to draw once. If you use the Paint handler technique, your drawing code gets called each time the form needs to redraw itself.

Edit:

Here's some code that illustrates my Paint handler information:

private void Form_Paint(object sender, PaintEventArgs e)
{
   e.Graphics.Clear();  // clear any and all circles being drawn

   if (CircleIsVisible)
   {
     e.Graphics.DrawEllipse( ... ); // OR, DrawImage( ) as in your example
   }
}

private void MouseDoubleClick (object sender, MouseEventArgs e)
{
   CircleIsVisible = true;
   Invalidate();  // triggers Paint event
}

If you're drawing bitmaps, I would load the bitmap once and store it as a class variable. This way you don't need to hit the hard drive each time you want to draw. Dispose of the bitmap when you dispose of your class (in this case, your window).

Charlie Salts
Thanks for the code snippet, it sounds like a good solution. Yet I have another question: I still prefer to use a bitmap instead of DrawEllipse(), since I need to draw icons. Now, say I have thousands of drawn icons, will this solution hurt performance? I mean, what is the cost of Clear() and DrawImage() if the bitmap is stored as a class member ?
ET
I only mentioned DrawEllipse since Hun1Ahpu mentioned it, and is what I would do, since I prefer managing code, rather than managing files.
Charlie Salts
Now, as for performance, think about the following. I'm not sure what the average hard drive seek and read times are these days, but they are several orders of magnitude *slower* than reading from RAM. There's always a memory-speed tradeoff and it depends on what your goals are. What you can do is add those icons to a resource file - your icons will be loaded into memory at runtime so your app might take longer to load initially, but drawing will be speedy.
Charlie Salts
Additional thought: if you find you only use a small subset of those icons, you *could* cache them as you load them. Then you only load the ones you need, and keep the ones you know you've already used (and may use in the future). It really all depends on what you're trying to do.
Charlie Salts
A: 

I thinks you should clear all of the image you draw before your next double click.
Such as Graphics.Clear().
On the other hand, you should not to create Graphics object or dispose it every time.

Edwin Tai
A: 

If you have simple background color you could use Graphics.DrawEllipse to draw Circles and then just change circle color to the background color. Also you need to have a Collection of all circles you draw so you can access any circle that you've drawn.

Hun1Ahpu
What if I use a background image, or I wanna draw some icon instead of circle?
ET
I was just guessing if you not. You can add this info to your question
Hun1Ahpu
You are right. Thanks for the response, I didnt try to offend, of course.
ET