Drawing Lines and Simple Shapes

Drawing lines or the outline of a shape requires the use of a pen. Filling an area, particularly the interior of a shape, is accomplished with a brush. The simple Windows Forms example in Listing 3.5.1 shows these operations. This is a self-contained, hand-edited example, so Visual Studio.Net is not needed.

NOTE

A word about graphics object management under GDI+ for Windows Forms. The garbage collection heap, as you know by now, does memory management under .NET for you. Technically, there is no need to worry about reclaiming your objects by deleting them because the garbage collector will do it for you eventually.

This is also true for graphical operations that create pens and brushes. However, an intense graphics routing could create many thousands of pens or brushes during each draw cycle and, in circumstances such as this, the garbage collector might not be quick enough to reclaim all the objects, causing a large number of dead items to be left on the heap for a considerable period of time.

To minimize the amount of work the garbage collector does, you should, wherever possible, explicitly invoke the Dispose() method on pens, brushes, and other such objects. This reclaims the memory in the object and tells the garbage collector not to bother with them.

In certain examples, you will see the declaration of the object inline, for example, DrawRectangle(new Pen(Color.Red),.... This will not cause a memory leak of the pen, it simply defers reclamation of the object when it's no longer in scope. In other examples, you will see explicit use of, for example, myPen.Dispose(). This is the recommended method for highest memory performance.


Listing 3.5.1. DrawLines.cs: Drawing Lines and Filling Rectangles
 1: using System;
 2: using System.Drawing;
 3: using System.Windows.Forms;
 4:
 5: class drawlines : System.Windows.Forms.Form
 6: {
 7:    Timer t;
 8:    bool BackgroundDirty;
 9:
10:    public void TickEventHandler(object sender, EventArgs e)
11:    {
12:       Invalidate();
13:    }
14:
15:    public void OnPaint(object sender, PaintEventArgs e)
16:    {
17:       // the current graphics object for
18:       // this window is in the PaintEventArgs
19:
20:       Random r=new Random();
21:
22:       Color c=Color.FromArgb(r.Next(255),r.Next(255),r.Next(255));
23:       Pen p=new Pen(c,(float)r.NextDouble()*10);
24:       e.Graphics.DrawLine(p,r.Next(this.ClientSize.Width),
25:                         r.Next(this.ClientSize.Height),
26:                         r.Next(this.ClientSize.Width),
27:                         r.Next(this.ClientSize.Height));
28:       p.Dispose();
29:    }
30:
31:    protected override void OnPaintBackground(PaintEventArgs e)
32:    {
33:       // When we resize or on the first time run
34:       // we'll paint the background, otherwise
35:       // it will be left so the lines build up
36:       if(BackgroundDirty)
37:       {
38:          BackgroundDirty = false;
39:          // We could call base.OnPaintBackground(e);
40:          // but that doesn't show off rectangle filling
41:          e.Graphics.FillRectangle(new SolidBrush(this.BackColor),
42:                                  this.ClientRectangle);
43:       }
44:
45:    }
46:
47:    public void OnSized(object sender, EventArgs e)
48:    {
49:       BackgroundDirty=true;
50:       Invalidate();
51:    }
52:
53:    public drawlines()
54:    {
55:       t=new Timer();
56:       t.Interval=300;
57:       t.Tick+=new System.EventHandler(TickEventHandler);
58:       t.Enabled=true;
59:       this.Paint+=new PaintEventHandler(OnPaint);
60:       this.SizeChanged+=new EventHandler(OnSized);
61:       this.Text="Lines and lines and lines";
62:       BackgroundDirty = true;
63:    }
64:
65:    static void Main()
66:    {
67:       Application.Run(new drawlines());
68:    }
69: };
					

Compile Listing 3.5.1 by using the following command line:

csc /t:winexe drawlines.cs

Lines 53–62 set up the application by creating a timer and by adding the OnPaint handler to the Paint event list. It also adds an event handler for the SizeChanged event, so that we can detect when a new background needs painting.

Lines 10–13 are a simple Tick event handler that just invalidates the window. And lines 15–29 are the paint handler that creates a pen and draws a line between two random coordinates onscreen.

Lines 31–43 paint the background for us. The reason that it's done this way is so that the invalidation of the screen doesn't paint over the lines already drawn. You can take this out if you like to see what happens. It illustrates how a brush fills a rectangle.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.181.154