Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


GDI+ Drawing Page, Part I : Page 5

With the .NET Forms and Drawing class libraries you can create a drawing application C! la Visio that allows users to drag and draw shapes, select those shapes, and move them about the form.


The Paint Event
Now that you know how to capture the bounds of the mouse's movement via a corresponding Rectangle (m_captureR), you need to display this rectangle to the user. To do so, force the control to re-paint using the following line of code inside the MouseMove event:

The Invalidate method of the Control class allows a specific region of the control to be invalidated, which forces it to be repainted. You can intercept this repaint inside the control's Paint event. You can see a complete listing of this event in Listing 3.

The code to display the drawn shape to the user turns out to be pretty straightforward. You first have to verify that the application is in capture mode by checking the member variable, m_capture. You also have to make sure that the user has indicated that they intend to draw something (m_draw). The resulting If statement looks like this:

   if (m_capture & m_draw != DrawType.Nothing)
Drawing the captured rectangle is just as simple. You create a private routine that takes a reference to a valid System.Drawing.Graphics instance as a parameter (passed in from the PaintEventArgs in the Paint event). This routine, called DrawCaptureR, renders the captured rectangle to the control.

To accomplish this rendering feat, first create an instance of the System.Drawing.Pen class. This class, as its name implies, represents a pen that has an ink color and line thickness. For the ink color, let's use a green brush provided by the System.Drawing.Brushes class. Set the pen's thickness (or width) to 1 point as follows:

   Pen p = new Pen(Brushes.Green, 1);
Next use the System.Drawing.Drawing2D.DashStyle enumeration to make the pen look like a series of dashes:

   p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
Finally, verify what the user intended to draw to the control (via the local m_draw) and then output the element to the control's surface using the appropriate method of the Graphics class (in this instance, DrawRectangle):

   if (m_draw==DrawType.Rectangle)
     g.DrawRectangle(p, m_captureR);      
     g.DrawEllipse(p, m_captureR);      
The MouseUp Event
Now that you have successfully captured the drag effect of the mouse and rendered the results to the page control's surface, you need to lock these results to the page once the user releases their drag (by releasing the mouse button). In addition, you need to store this element so it could be re-drawn to the screen later if need be.

To handle these tasks, you intercept the control's MouseUp event. Inside this event (complete code in Listing 4), you turn off capture mode by setting m_capture to false. This stops the control from processing further mouse movement via the MouseMove event. Next, you need to store the resulting graphical element in the object. To do so, you create a variable of the type Element. Then, based on the current drawing type (rectangle or ellipse), you cast that variable as the concrete Element class.

   el = new RectElement(
   m_captureR.Location, m_captureR.Size,
   new Pen(Brushes.Black, 2), m_fill);
Now you need to store this element inside the Document. If you remember from the object model, the Document class that you create maintains a reference to the Elements collection. And of course, the PageControl class holds a reference to the Document class. Therefore, from within the PageControl's MouseUp event you have to add the newly created Element instance to the Elements collection as follows:

One requirement for each Element instance is that it can draw itself. Therefore, all that was left to do in the MouseUp event was force the control to repaint. The control's Paint event will then handle drawing any elements stored in the associated Document instance.

To draw these stored elements, look at the private routine inside the PageControl class—DrawElements. The PageControl's Paint event calls DrawElements, passing it a handle to the control's Graphics surface. This routine simply loops through the Elements collection and calls the Draw method of each Element instance (forwarding it the Graphics handle).

The Draw methods for each of the Element classes are all very similar. First create a GraphicsContainer instance with the call:

   GraphicsContainer gc = g.BeginContainer();
This call to BeginContainer allows you to cache subsequent calls to the Graphics handle before rendering to the screen.

Next, create a System.Drawing.Rectangle instance and draw it to the Graphics surface, then fill accordingly. These calls are as follows:

   Rectangle r = 
    new Rectangle(this.Position, this.Size);
     new Pen(new SolidBrush(this.PenColor),    
     this.PenThickness), r);
     new SolidBrush(this.FillColor), r);
Finally, call the EndContainer method of the Graphics class to indicate that your application can now render the given element to the user's screen:


Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date