The Drawing Namespace

The System.Drawing namespace includes several classes and structures. The most important of them are summarized, briefly, in Table 10-1.

Table 10-1. Drawing namespace classes and structures

Class

Description

Bitmap

Encapsulates a GDI+ bitmap, i.e., pixel data representing an image.

Brush

Abstract base class. Used to fill the interiors of graphical shapes.

Brushes

Provides static brush definitions for all standard colors.

Color

Structure representing colors, e.g., Color.Green.

Font

Defines a format for text, including font face, and sizeEncapsulates a typeface, size, style, and effects.

FontFamily

Group of type faces with the same basic design.

Graphics

Encapsulates a GDI+ drawing surface.

Icon

Transparent bitmaps used for Windows icons.

Image

Abstract base class common to the Bitmap, Icon, and Metafile classes.

Pen

Defines an object used to draw lines and curves.

Pens

Provides static Pen definitions for all the standard colors.

Point

Structure used to represent an ordered pair of integers. Typically used to specify two-dimensional Cartesian coordinates.

PointF

Same as Point, but uses a floating-point number (float in C#, Single in VB.NET) rather than an integer.

Rectangle

Structure that represents the location and size of a rectangular region.

RectangleF

Same as Rectangle, but uses floating-point values (float in C#, single in VB.NET) rather than integers.

Size

Structure that represents the size of a rectangular region as an order pair (Point) representing width and height.

SizeF

Same as Size, but uses PointF rather than Point.

SystemBrushes

A utility class with 21 static, read-only properties that return objects of type Brush (each of a different color).

SystemPens

A utility class with 15 static, read-only properties that return objects of type Pen (each of a different color).

Arguably the most important class for graphics programming is (surprise!) the Graphics class. The other classes will be described as they are encountered, but before proceeding, let's examine the Graphics class in detail.

10.1.1 The Graphics Class

The Graphics class represents a GDI+ drawing surface. A Graphics object maintains the state of the drawing surface, including the scale and units, as well as the orientation of the drawing surface.

The Graphics class provides many properties. The most commonly used properties are listed in Table 10-2, most of which will be demonstrated later in this chapter.

Table 10-2. Graphics properties

Property

Type

Description

Clip

Region

Read/write. Specifies the area available for drawing.

DpiX / DpiY

Float / single

Read/write. The horizontal and vertical resolution (respectively) of the Graphics object in dots per inch.

PageScale

Float / single

Read/write. The scaling between world units and page units for this Graphics object.

PageUnit

GraphicsUnit

Read/write. The unit of measure for page coordinates. Valid values are members of the GraphicsUnit enumeration, listed in Table 10-3.

The PageScale sets the scaling between the world units and the page units. To understand these concepts, you must first understand coordinates.

10.1.1.1 Coordinates

The French philosopher René Descartes (1596-1650) is best known today for stating that while he may doubt, he can not doubt that he exists. This is summarized in his oft-quoted statement Cogito Ergo Sum (I think, therefore I am).[1]

[1] Philosopher joke: Rene Descartes goes into McDonald's and orders a Big Mac. The person behind the counter asks, "You want fries with that?" Descartes replies "I think not," and immediately disappears.

Among mathematicians, Descartes may be best known for inventing Analytical Geometry and what are now called Cartesian coordinates. In a classic Cartesian coordinate system, you envision an x axis and a y axis, as shown in Figure 10-1, with the origin (0,0) at the center. The values to the right of the origin and above the origin are positive, and the values to the left and below are negative.

Figure 10-1. Cartesian coordinates

figs/pnwa_1001.gif

In most graphical programming environments, like in Windows, the coordinate system has its origin at the upper-lefthand corner, rather than in the center, and you count upward to the right and down, as shown in Figure 10-2. The coordinates you pass to the various drawing methods of the Graphics class are called world coordinates.

Figure 10-2. World coordinates

figs/pnwa_1002.gif

10.1.1.2 Transforms introduced

These world coordinates are transformed into page coordinates by world transformations. You'll use these world transformations (e.g., TranslateTransform, ScaleTransform, and RotateTransform) later in this chapter to set the center and the orientation of your coordinate system. When drawing a clock face, for example, setting the origin (0,0) to the center of the clock is more convenient.

Page transforms convert page coordinates into device coordinates: pixels relative to the upper-lefthand corner of the client area on your monitor, bitmap, page, etc. The page transforms are the PageUnit and PageScale properties of the Graphics object, which were listed in Table 10-2.

The PageUnit property chooses the unit in which you will make your transformations and scale your drawings. These Units are one of the GraphicsUnits-enumerated values shown in Table 10-3.

Table 10-3. GraphicsUnits enumeration

Enumerated value

Unit of measure

Display

1/75 of an inch

Document

1/300 of an inch

Inch

1 inch

Millimeter

1 millimeter

Pixel

1 Pixel

Point

1/72 of an inch

World

World unit

Using the unit described by the PageUnit, you can set the PageScale that specifies the value for scaling between world units and page units for the current Graphics object. You'll see this at work later in this chapter when you'll create a scale of 2000 units by 2,000 unitsthat is, rather than working in pixels or inches, you'll create an arbitrary unit that is 1/2000 of the width (or height) of your screen.

10.1.2 Graphics Methods

The Graphics class has many methods for drawing to the graphics device. They include methods that begin with Draw, shown here:

DrawArc

DrawIcon

DrawPath

DrawBezier

DrawIconUnstretched

DrawPie

DrawBeziers

DrawImage

DrawPolygon

DrawClosedCurve

DrawImageUnscaled

DrawRectangle

DrawCurve

DrawLine

DrawRectangles

DrawEllipse

DrawLines

DrawString

They also include methods that begin with Fill, shown here:

FillClosedCurve

FillPie

FillRectangles

FillEllipse

FillPolygon

FillRegion

FillPath

FillRectangle

 

(Draw methods draw the outline of the figure; Fill methods fill the interior with the color of the current brush).

The methods you'll use in this chapter, and other commonly used methods, are summarized in Table 10-4.

Table 10-4. Graphics methods

Method

Description

Clear

Clear the drawing area and fill it with the specified color.

DrawString

Draw a string at a particular location using a particular brush and font.

DrawLine

Draw a line connecting two points.

FillEllipse

Fill an ellipse defined by a bounding rectangle.

MeasureString

Return the size of a string when drawn with a specific font within the context of the current Graphics object.

Restore

Restore the state of a Graphics object (see Save, below).

RotateTransform

Apply a rotation to the transformation matrix of a Graphics object.

Save

Save the state of a Graphics object.

ScaleTransform

Apply a scaling operation to the transformation matrix of a Graphics object.

TransformPoints

Transform an array of points from one coordinate space to another, using the current world and page transformations.

TranslateTransform

Apply a translation operation on the transformation matrix.

Create the second hand dot shown in Figure 10-5 using the FillElipse method, and create the clock hands using the DrawLine method. Write characters using the DrawString method. You can learn more about this process below.

Save and Restore are two important methods in the Graphics class. The Save method saves the current state of the Graphics class and returns that state in a GraphicsState object. You do not need to know anything about the internal mechanism of the GraphicsState object. It can be treated as a token that you pass into Restore, which restores the saved state of the Graphics object. Thus, you might write code that looks like this:

figs/csharpicon.gif

GraphicsState state = myGraphicsObject.Save( );
// make transformations here
myGraphicsObject.Restore(state);

figs/vbicon.gif

dim state as GraphicsState = myGraphicsObject.Save( )
'' make transformations here
myGraphicsObject.Restore(state)

Using Save and Restore allows you to change the scale or orientation of your Graphics object, and then set it back to the way it was before you transformed it.

The transformation methods are detailed later in this chapter.

10.1.3 Obtaining a Graphics Object

You can obtain a Graphics object in many different ways. Two of the ways involve the Paint event, which is described in detail in the next section. You can add an event handler to the Paint event delegate or override the OnPaint event handler method. In either case, the event handler method takes a PaintEventArgs parameter, which has a property that returns a Graphics object.

figs/csharpicon.gif

protected override void OnPaint ( PaintEventArgs e )
{
 Graphics g = e.Graphics;

figs/vbicon.gif

protected override sub OnPaint (e as PaintEventArgs)
 dim g as Graphics = e.Graphics

If you override the OnPaint method, you should always finish by chaining up to the base class, forcing it to be invoked. To do so, use the following line of code:

figs/csharpicon.gif

base.OnPaint(e);

figs/vbicon.gif

myBase.OnPaint(e)

Another way to obtain a Graphics object is to call the CreateGraphics method on a control or form:

figs/csharpicon.gif

Graphics g = this.CreateGraphics( );

figs/vbicon.gif

dim g as Graphics = me.CreateGraphics( )

If you do create a Graphics object using CreateGraphics, be sure to call the Dispose method of the Graphics object when you are done with it. Never store a Graphics object as a member variable of your own class. Create or obtain the Graphics object when you need it and then dispose of it properly. The C# using keyword can help automate this process for you.

 

10.1.4 Color Structure

The System.Drawing namespace provides a Color structure to represent standard system-defined colors. Whenever a color is needed, you can use any of the 141 public static properties of the Color structure. These properties include such standbys as Red, Blue, Green, Gray, and Black; variations on the standards such as LightBlue, LightGreen, LightPink, and DarkOrange; and gems such as LightGoldenRodYellow, MediumSlateBlue, and PapayaWhip. The complete list of standard colors is provided in the Appendix.

In addition to the standard colors, 26 members of the SystemColor enumeration represent the colors used for various elements of the Windows desktop. They include such items as ActiveBorder, Desktop, and WindowFrame. The complete SystemColor enumeration is also shown in the Appendix.

The combination of the standard colors and the SystemColors comprise the KnownColor enumeration.

The color system is based on the ARGB model, where A stands for Alpha, or the transparency of the color, and RGB stands for Red-Green Blue. One byte is allocated each for the Alpha and the three primary colors. An Alpha value of 0 is transparent and FF is opaque. Likewise, a zero value for a color (R, G, or B) indicates that none of that color is present, while a value of FF indicates that the color is full on.

In addition to the static properties representing the standard colors, several commonly used instance properties of the Color structure are listed in Table 10-5.

Table 10-5. Color structure instance properties

Value

Description

A

Returns byte value of Alpha component

R

Returns byte value of red component

G

Returns byte value of green component

B

Returns byte value of blue component

Name

Returns the name of the color, either user-defined, a known color, or an RGB value

10.1.5 Geometric StructuresPoints, Rectangles, and Sizes

The System.Drawing namespace provides several structures for representing a location (Point and PointF), a rectangular area (Rectangle and RectangleF), and a size (Size and SizeF).

All of these structures consist of a pair of read/write ordered pair of numbers. The versions without the trailing F in the name take an ordered pair of ordered pairs of integers (four integers in total) and the versions with the trailing F take an ordered pair of ordered pairs of floating-point numbers (float in C# or single in VB.NET). The numbers typically represent pixels. They can also represent other units, such as Inch or Millimeter, hence the need for floating-point as well as integer values.

The integer versions of these structures can be cast to the floating-point version:

figs/csharpicon.gif

PointF ptf;
Point pt = null;
ptf = pt;

figs/vbicon.gif

dim ptf as PointF
dim pt as Point
ptf = pt

You cannot cast in the opposite direction, since information may be lost. However, all three integer versions provide static methods (Ceiling, Round, and Truncate) for converting from the floating-point version to the integer version.

In the Point/PointF structure, the first number represents the x, or horizontal coordinate in a two-dimensional Cartesian coordinate system. The second number represents the y, or vertical coordinate.

The Size/SizeF structures are similar to the Point/PointF structures, except that the ordered pair of numbers represent the Width and Height properties of a rectangular region.

The Rectangle and RectangleF structures represent a rectangular region. Each has two constructors, listed in Table 10-6. The first constructor takes a Point (or PointF) structure and a Size (or SizeF) structure. The second constructor takes four numbers, either integers or float/singles. The first two numbers represent the x and y coordinates of the upper-left corner of the rectangle, and the second two numbers represent the width and height of the rectangle.

Table 10-6. Rectangle and RectangleF constructors

Rectangle

Point, Size

 

Integer, Integer, Integer, Integer

RectangleF

PointF, SizeF

 

Integer, Integer, Integer, Integer

The Rectangle and RectangleF structures also provide several properties for either getting information about the rectangle or setting properties. These properties are listed in Table 10-7.

Table 10-7. Rectangle and RectangleF properties

Property

Type

Description

Bottom

Integer

Float/single

Read-only. Returns the y coordinate of the bottom edge of the rectangle.

Height

Integer

Float/single

Read/write. The height of the rectangle.

IsEmpty

Boolean

Read-only. Returns true if all numeric properties have a value of zero.

Left

Integer

Float/single

Read-only. Returns the x coordinate of the left edge of the rectangle.

Location

Point/PointF

Read/write. The point at the upper-left corner of the rectangle.

Right

Integer

Float/single

Read-only. Returns the x coordinate of the right edge of the rectangle.

Size

Size/SizeF

Read/write. The size of the rectangle.

Top

Integer

Float/single

Read-only. Returns the y coordinate of the top edge of the rectangle.

Width

Integer

Float/single

Read/write. The width of the rectangle.

X

Integer

Float/single

Read/write. The x coordinate of the upper-left corner of the rectangle.

Y

Integer

Float/single

Read/write. The y coordinate of the upper-left corner of the rectangle.

10.1.6 Brush and Brushes

A Brush object is used to fill the interior spaces of graphical shapes. The Brush class is abstract (MustInherit), and five different classes are derived from Brush, listed in Table 10-8.

Table 10-8. Brush-derived classes

Class

Description

HatchBrush

A rectangular brush with a hatch style from the HatchStyle enumeration, such as BackwardDiagonal, DarkVertical, Divot, and Percent60. The ForegroundColor property gets the color of the lines and the BackgroundColor property gets the color of the space behind the lines.

LinearGradientBrush

A brush with a linear gradient. Properties such as Blend, GammaCorrection, and Transform allow you to change the appearance programatically.

PathGradientBrush

A brush that fills a graphical shape with a gradient. Properties such as Blend, CenterColor, and Transform allow you to change the appearance programatically.

SolidBrush

A brush that fills a graphical shape with a color. Valid colors are members of the Color structure.

TextureBrush

A brush that fills a graphical shape with a texture. The texture can come from an Image object, either a bitmap or a metafile.

For easy access to the colored brushes, a Brushes class (note the plural) contains only static (shared), read-only properties of type Brush corresponding to each standard color. This Brushes class often provides the Brush object used in calls to the DrawString method.

If you explicitly create a Brush (or Pen), you must explicitly dispose of it, but you must not dispose of any brushes returned to you by Brushes, SystemBrushes, Pens, or SystemPens.

 

10.1.7 Pen and Pens

The Pen and Pens classes are similar to the Brush and Brushes classes, except they are used for drawing lines and curves rather than filling graphical shapes. The constructors of the Pen class take either a Brush object or a Color as an argument. Additionally, you can pass in a floating-point number (float in C#, single in VB.NET) that specifies the width of the Pen object.

As with the Brushes class, there is a Pens class (note the plural) for easy access to a Pen object of a standard color. The Pens class contains static members corresponding to each standard color. The following code snippet demonstrates one way to instantiate and use a Pen object.

figs/csharpicon.gif

Pen pn = Pens.LimeGreen;
pn.EndCap = LineCap.ArrowAnchor;
pn.Width = 20;
g.DrawLine(pn,0,0,0,50);

figs/vbicon.gif

Dim pn as Pen = Pens.LimeGreen
pn.EndCap = LineCap.ArrowAnchor
pn.Width = 20
g.DrawLine(pn, 0, 0, 0, 50)

Table 10-9 lists many of the most commonly used properties of the Pen class. Many of them will be demonstrated in the Analog Clock project later in this chapter.

Table 10-9. Pen properties

Property

Type

Description

Alignment

PenAlignment

Read/write. Specifies the alignment for this Pen object relative to a theoretical line. Valid values are members of the PenAlignment enumeration, listed in Table 10-10.

Brush

Brush

Read/write. The Brush object that controls attributes of the pen (e.g., does the pen draw a solid or a pattern?).

Color

Color

Read/write. The color of the Pen. Legal values are members of the Color structure, e.g., Color.DarkGoldenrod.

DashCap

DashCap

Read/write. The cap style used at the beginning and end of the dashes that comprise a dashed line. Valid values are Flat, Round, and Triangle.

DashPattern

float[ ] / single( )

Read/write. An array of numbers specifying the lengths of alternating dashes and spaces.

DashStyle

DashStyle

Read/write. The style used for dashed lines. Valid values are members of the DashStyle enumeration, listed in Table 10-11.

EndCap

LineCap

Read/write. The enumerated arrow type. Valid values are members of the LineCap enumeration, listed in Table 10-12.

StartCap

LineCap

Read/write. The enumerated arrow type. Valid values are members of the LineCap enumeration, listed in Table 10-12.

Width

Float

The thickness of the drawn line.

Table 10-10. PenAlignment enumeration values

Value

Description

Center

Centered over the theoretical line

Inset

Positioned to the inside of the theoretical line

Left

Positioned to the left of the theoretical line

Outset

Positioned to the outside of the theoretical line

Right

Positioned to the right of the theoretical line

Table 10-11. DashStyle enumeration values

Value

Description

Custom

Custom style

Dash

Dashes

DashDot

Repeating pattern of dash-dot

DashDotDot

Repeating pattern of dash-dot-dot

Dot

Dots

Solid

Solid line

Table 10-12. LineCap enumeration values

Value

Description

AnchorMask

Mask to check if cap is an anchor cap

ArrowAnchor

Arrow-shaped anchor cap

Custom

Custom line cap

DiamondAnchor

Diamond-shaped anchor cap

Flat

Flat line cap

NoAnchor

No anchor

Round

Round line cap

RoundAnchor

Round anchor cap

Square

Square cap

SquareAnchor

Square anchor cap

Triangle

Triangular line cap

10.1.8 Paint Event

All controls have a Paint event, which is raised when the control is about to be drawn. You can add an event handler to the Paint event delegate to dictate how the control is drawn. Using the Paint event, for example, you can draw a string of text directly onto the client area of a form, as shown in Example 10-1 (in C#) and in Example 10-2 (in VB.NET).

For a complete discussion of delegates and events, see Chapter 4.

 

Example 10-1. Drawing a string with Paint event using C# (PaintDemo.cs)

figs/csharpicon.gif

using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace ProgrammingWinApps
{
 public class PaintDemo : Form
 {
 
 public PaintDemo( )
 {
 Text = "Paint Demonstration";
 Size = new Size(300,200);
 Paint += new PaintEventHandler(PaintHandler);
 }
 
 static void Main( ) 
 {
 Application.Run(new PaintDemo( ));
 }
 
 private void PaintHandler(object sender, PaintEventArgs e)
 {
 Graphics g = e.Graphics;
 g.DrawString("Look Ma, no label!", Font, Brushes.Black, 50, 75);
 }
 }
}

Example 10-2. Drawing a string with Paint event using VB.NET (PaintDemo.vb)

figs/vbicon.gif

imports System
imports System.Drawing
imports System.Windows.Forms
 
namespace ProgrammingWinApps
 public class PaintDemo : inherits Form
 
 public sub New( )
 Text = "Paint Demonstration"
 Size = new Size(300,200)
 AddHandler Paint, AddressOf PaintHandler
 end sub
 
 public shared sub Main( ) 
 Application.Run(new PaintDemo( ))
 end sub
 
 private sub PaintHandler(ByVal sender as object, _
 ByVal e as PaintEventArgs)
 dim g as Graphics = e.Graphics
 g.DrawString("Look Ma, no label!", Font, Brushes.Black, 50, 75)
 end sub
 end class
end namespace

When either program in Example 10-1 or Example 10-2 is compiled and run, you will get the form shown in Figure 10-3.

Figure 10-3. Paint event demonstration

figs/pnwa_1003.gif

Both versions of the PaintDemo program start by referencing the required namespaces: System, System.Drawing, and System.Windows.Forms. Inside the constructor of each program, the Text and Size properties are set, and the PaintHandler method is added to the delegate for the Paint event:

figs/csharpicon.gif

Text = "Paint Demonstration";
Size = new Size(300,200);
Paint += new PaintEventHandler(PaintHandler);

figs/vbicon.gif

Text = "Paint Demonstration"
Size = new Size(300,200)
AddHandler Paint, AddressOf PaintHandler

Remember that all of these properties (and events) are implicitly members of the classi.e., the PaintDemo form. You can make this explicit by using the appropriate lines of code:

figs/csharpicon.gif

this.Text = "Paint Demonstration";
this.Size = new Size(300,200);
this.Paint += new PaintEventHandler(PaintHandler);

figs/vbicon.gif

Me.Text = "Paint Demonstration"
Me.Size = new Size(300,200)
Me.AddHandler Paint, AddressOf PaintHandler

The PaintHandler method is a typical event handler, taking two arguments. The first is of type object and the second is of type PaintEventArgs, which has the two read-only properties listed in Table 10-13.

Table 10-13. PaintEventArgs properties

Property

Type

Description

ClipRectangle

Rectangle

The rectangle to paint

Graphics

Graphics

The Graphics object used to paint

A new Graphics object is instantiated from the PaintEventArgs argument.

figs/csharpicon.gif

Graphics g = e.Graphics;

figs/vbicon.gif

dim g as Graphics = e.Graphics

Then the DrawString method is invoked to render the desired text string on the form client area. The DrawString method has several overloaded versions, but all of them take at least the string to draw, the font to use, the brush to use (which controls the color and appearance of the characters), and a location:

figs/csharpicon.gif

g.DrawString("Look Ma, no label!", Font, Brushes.Black, 50, 75);

figs/vbicon.gif

g.DrawString("Look Ma, no label!", Font, Brushes.Black, 50, 75)

In this example, the font used is the current font for the form (it also could have been written as this.Font in C# or me.Font in VB.NET), the brush is Black, and the location of the upper-left corner of the text string is 50 units in from the left edge of the client area and 75 units down from the top.

10.1.8.1 Overriding the OnPaint method

The programs shown in Example 10-1 and Example 10-2 worked by adding an event handler method to the Paint event. You can accomplish the same outcome by overriding the OnPaint event directly just as you might override any virtual method. The Control class defines the OnPaint method as follows:

figs/csharpicon.gif

protected virtual void OnPaint( PaintEventArgs e );

figs/vbicon.gif

Overridable Protected Sub OnPaint( ByVal e As PaintEventArgs )

Example 10-3 (in C#) and in Example 10-4 (in VB.NET) demonstrate how to override the OnPaint event. The differences from the previous examples are highlighted.

Example 10-3. Overriding the OnPaint event in C# (PaintOverride.cs)

figs/csharpicon.gif

using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace ProgrammingWinApps
{
 public class PaintOverride : Form
 {
 
 public PaintOverride( )
 {
 Text = "Paint Demonstration";
 Size = new Size(300,200);
 }
 
 static void Main( ) 
 {
 Application.Run(new PaintOverride( ));
 }
 
 protected override void OnPaint(PaintEventArgs e)
 {
 Graphics g = e.Graphics;
 g.DrawString("Look Ma, I'm overridden!", Font, Brushes.Black, 50, 75);
 base.OnPaint(e);
 }
 }
}

Example 10-4. Overriding the OnPaint event in VB.NET (PaintOverride.vb)

figs/vbicon.gif

imports System
imports System.Drawing
imports System.Windows.Forms
 
namespace ProgrammingWinApps
 public class PaintOverride : inherits Form
 
 public sub New( )
 Text = "Paint Demonstration"
 Size = new Size(300,200)
 end sub
 
 public shared sub Main( ) 
 Application.Run(new PaintOverride( ))
 end sub
 
 protected overrides sub OnPaint(ByVal e as PaintEventArgs)
 myBase.OnPaint(e)
 dim g as Graphics = e.Graphics
 g.DrawString("Look Ma, I'm overridden!", _
 Font, Brushes.Black, 50, 75)
 end sub
 end class
end namespace

In Example 10-3 and Example 10-4, no methods are added to any event delegates. Instead, the protected OnPaint method is overridden. When overriding an event handler, the only required argument is the event argumentin this case, PaintEventArgs.

The last line in the overridden method chains up to the base method (invokes the base method) to ensure that all the base class functionality will be implemented and that any other methods registered with the delegate will be notified. This is done with the line:

figs/csharpicon.gif

base.OnPaint(e);

figs/vbicon.gif

myBase.OnPaint(e)

The remaining two lines in the overridden method are the same as in the previous examples.

10.1.8.2 Forcing a paint eventthe Invalidate method

You can force a region to redraw by calling the Invalidate method on a control. This method does not actually raise the Paint event, but invalidates the area of the control or a region within the control. Once an area or region has been invalidated, it will be redrawn. This will occur when all current events are finished processing. If you want the redraw to occur immediately, call the Update method after calling the Invalidate method.

The Invalidate method is overloaded with six different versions. The parameters supplied to the method dictate exactly what part of the control will be invalidated. The overloaded versions are listed in Table 10-14.

Table 10-14. Invalidate methods

Method Call

Description

Invalidate( )

Invalidates the region of the control

Invalidate(Boolean)

If Boolean is true, invalidates the child controls

Invalidate(Rectangle)

Invalidates the region specified by the Rectangle

Invalidate(Region)

Invalidates the specified Region

Invalidate(Rectangle, Boolean)

Invalidates the region specified by the Rectangle, and if Boolean is true, invalidates the child controls

Invalidate(Region, Boolean)

Invalidates the specified Region, and if Boolean is true, invalidates the child controls

Use of the Invalidate method is shown in Example 10-5 (in C#) and in Example 10-6 (in VB.NET). The lines of code differing from the basic examples in Example 10-1 and Example 10-2 are highlighted.

Example 10-5. Invalidate method in C# (PaintInvalidate.cs)

figs/csharpicon.gif

using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace ProgrammingWinApps
{
 public class PaintInvalidate : Form
 {
 private Button btn;
 
 public PaintInvalidate( )
 {
 Text = "Paint Invalidate Demonstration";
 Size = new Size(300,200);
 
 btn = new Button( );
 btn.Parent = this;
 btn.Location = new Point(25,25);
 btn.Text = "Update";
 btn.Click += new System.EventHandler(btn_Click);
 }
 
 static void Main( ) 
 {
 Application.Run(new PaintInvalidate( ));
 }
 
 protected override void OnPaint(PaintEventArgs e)
 {
 base.OnPaint(e);
 Graphics g = e.Graphics;
 String str = "Look Ma, I'm overridden!";
 str += "
The time is " + DateTime.Now.ToLongTimeString( );
 g.DrawString(str, Font, Brushes.Black, 50, 75);
 }
 
 private void btn_Click(object sender, EventArgs e)
 {
 Invalidate( );
 }
 }
}

Example 10-6. Invalidate method in VB.NET (PaintInvalidate.vb)

figs/vbicon.gif

imports System
imports System.Drawing
imports System.Windows.Forms
 
namespace ProgrammingWinApps
 public class PaintInvalidate : inherits Form
 
 private WithEvents btn as Button
 
 public sub New( )
 Text = "Paint Invalidate Demonstration"
 Size = new Size(300,200)
 
 btn = new Button( )
 btn.Parent = me
 btn.Location = new Point(25,25)
 btn.Text = "Update"
 end sub
 
 public shared sub Main( ) 
 Application.Run(new PaintInvalidate( ))
 end sub
 
 protected overrides sub OnPaint(ByVal e as PaintEventArgs)
 myBase.OnPaint(e)
 dim g as Graphics = e.Graphics
 dim str as string = "Look Ma, I'm overridden!"
 str += vbCrLf + "The time is " + DateTime.Now.ToLongTimeString( )
 g.DrawString(str, Font, Brushes.Black, 50, 75)
 end sub
 
 private sub btn_Click(ByVal sender as object, _
 ByVal e as EventArgs) _
 Handles btn.Click
 Invalidate( )
 end sub
 end class
end namespace

When either program is compiled and run, you get something similar to that shown in Figure 10-4. Clicking on the button updates the time displayed in the client area of the form.

Figure 10-4. Paint Invalidate program

figs/pnwa_1004.gif

The Invalidate method is called against the Form object. The line:

Invalidate( )

is implicitly the same as:

figs/csharpicon.gif

this.Invalidate( );

figs/vbicon.gif

me.Invalidate( )

Another way to force a Form to invalidate itself and cause the Paint event to be raised is to set the ResizeRedraw property to true. This will cause the object, the Form in this case, to redraw itself every time the object is resized. In fact, if an application is not behaving the way you might expect when resizing, then setting this property to true might alleviate the problem.

Windows Forms and the .NET Framework

Getting Started

Visual Studio .NET

Events

Windows Forms

Dialog Boxes

Controls: The Base Class

Mouse Interaction

Text and Fonts

Drawing and GDI+

Labels and Buttons

Text Controls

Other Basic Controls

TreeView and ListView

List Controls

Date and Time Controls

Custom Controls

Menus and Bars

ADO.NET

Updating ADO.NET

Exceptions and Debugging

Configuration and Deployment



Programming. NET Windows Applications
Programming .Net Windows Applications
ISBN: 0596003218
EAN: 2147483647
Year: 2003
Pages: 148

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net