Tải bản đầy đủ (.pdf) (82 trang)

mcts self paced training kit exam 70-536 microsoft net framework 3.5 application development foundation phần 4 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (397.26 KB, 82 trang )

214 Chapter 5 Review
Case Scenarios
In the following case scenarios, you apply what you’ve learned about how to imple-
ment and apply serialization, as well as how to upgrade applications that make use of
serialization. You can find answers to these questions in the “Answers” section at the
end of this book.
Case Scenario 1: Choosing a Serialization Technique
You are an application developer for City Power & Light. For the last year, you and
your team have been creating a distributed .NET Framework solution to replace the
antiquated system that currently accounts for electrical usage and distributes bills to
customers. You have created components for monitoring electrical usage, and you are
at the stage of development when you need to transmit usage information to the bill-
ing system. Your manager asks you to interview key people and then answer some
questions about your design choices.
Interviews
The following is a list of company personnel you interviewed and their statements:
Q Billing System Development Manager “I’ve already got my guy working on this,
and he has built methods with .NET that accept your Usage objects and add bill-
ing information to the database. So we just need you to create those objects and
send them over the internal network to us.”
Q Network Manager “All the accounting and billing servers are on the same sub-
net, so you don’t have to worry about your network traffic going through any
firewalls. I would like you to try and minimize the bandwidth used—we have
millions of accounts, and that subnet is close to being saturated already.”
Questions
Answer the following questions for your manager:
1. Which serialization method will you use?
2. What changes will you need to make to your class to enable serialization?
3. About how many lines of code will you need to write to perform the serialization?
Chapter 5 Review 215
Case Scenario 2: Serializing Between Versions


You are an application developer working for Humongous Insurance. Recently, you
have launched version 1.0 of Incident, an application based on an earlier version of
the .NET Framework that tracks insurance events throughout their life cycle.
Subsequent to this successful launch, you have begun development of Incident 2.0.
Incident 2.0 is based on the latest version of the .NET Framework. During a planning
meeting, your manager asks you questions about how Incident 2.0 will handle the
upgrade process during deployment.
Questions
Answer the following questions for your manager:
1. In Incident 1.0, I know you save some user preferences, such as window posi-
tion, to a file by serializing your Preferences object using BinaryFormatter. Now
that the application will be based on a newer version of the .NET framework, will
you be able to deserialize those settings directly in Incident 2.0 if you don’t make
any changes to the Preferences class?
2. We have some feature requests that will require you to add more preferences. If
you add more members to the Preferences class, will you still be able to deserialize
settings stored from the previous version? If so, what special accommodations
will you need to make?
3. The IT department has requested we switch to using XML-based configuration
files so that they can edit them more easily. How could you deserialize the exist-
ing binary-formatted object, while serializing an XML object?
Suggested Practices
To help you successfully master the “Implementing serialization and input/output func-
tionality in a .NET Framework application” exam objective, complete the following tasks.
Serialize or Deserialize an Object or an Object Graph by Using
Runtime Serialization Techniques
For this task, you should complete at least Practices 1 and 2. If you want a better
understanding of how serialization can be used in the real world and you have the
resources needed to do Practice 3, complete it as well.
216 Chapter 5 Review

Q Practice 1 Using the last custom class that you created as part of your job, mod-
ify it so that it can be serialized. Then write an application to serialize and dese-
rialize it using BinaryFormatter. Examine the serialized data. Then modify the
application to use SoapFormatter. Examine the serialized data.
Q Practice 2 Examine the class that you used in Practice 1 and, if possible, identify
a member that does not need to be serialized. Modify your class so that the mem-
ber will not be serialized but will be defined automatically upon deserialization.
Q Practice 3 Write a client/server application to transfer an object between two
networked computers using serialization and deserialization.
Control the Serialization of an Object into XML Format by Using the
System.Xml.Serialization Namespace
For this task, you should complete all three practices to gain experience using XML
serialization with real-world classes and schema.
Q Practice 1 Write an application that uses XML serialization to serialize and
deserialize the last class that you created as part of your job.
Q Practice 2 Examine the class that you used in Practice 1 and, if possible, identify
a member that does not need to be serialized. Use an attribute to modify your
class so that the member will not be serialized.
Q Practice 3 Find an XML schema on the Internet and create a class that, when
serialized, conforms to that XML schema. Create the class using two different
techniques: manually and with Xsd.exe.
Implement Custom Serialization Formatting by Using the
Serialization Formatter Classes
For this task, you should complete at least Practices 1 and 2. If you want in-depth
knowledge of the serialization process, complete Practice 3 as well.
Q Practice 1 Using the last custom class that you created as part of your job, mod-
ify it so that it implements ISerializable and can be successfully serialized and
deserialized. Examine the members to determine whether you can optimize seri-
alization by omitting calculated values.
Q Practice 2 Create a class that provides methods for all four BinaryFormatter seri-

alization events.
Chapter 5 Review 217
Q Practice 3 Implement the IFormatter interface to create a custom formatter. Use
it during serialization and deserialization to understand the formatter’s role in
serialization.
Take a Practice Test
The practice tests on this book’s companion CD offer many options. For example, you
can test yourself on just one exam objective, or you can test yourself on all the 70-536
certification exam content. You can set up the test so that it closely simulates the expe-
rience of taking a certification exam, or you can set it up in study mode so that you can
look at the correct answers and explanations after you answer each question.
MORE INFO Practice Tests
For details about all the practice test options available, see the section ”How to Use the Practice
Tests” in the Introduction of this book.

219
Chapter 6
Graphics
You can use graphics to enhance the user interface of your applications, generate
graphical charts and reports, and edit or create images. The .NET Framework includes
tools that allow you to draw lines, shapes, patterns, and text. This chapter discusses
how to create graphics and images using the classes in the System.Drawing namespace.
NOTE WPF Graphics
.NET Framework versions 3.0 and later include Windows Presentation Foundation (WPF), which
provides robust graphics capabilities beyond those provided by the System.Drawing namespace.
However, the 70-536 certification exam covers only the System.Drawing namespace. Therefore, for
the purpose of this exam, you should disregard the WPF graphics capabilities.
Exam objectives in this chapter:
Q Enhance the user interface of a .NET Framework application by using the
Sysem.Drawing namespace

Q Enhance the user interface of a .NET Framework application by using brushes,
pens, colors, and fonts
Q Enhance the user interface of a .NET Framework application by using graphics,
images, bitmaps, and icons
Q Enhance the user interface of a .NET Framework application by using shapes
and sizes
Lessons in this chapter:
Q Lesson 1: Drawing Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Q Lesson 2: Working with Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Q Lesson 3: Formatting Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
220 Chapter 6 Graphics
Before You Begin
To complete the lessons in this chapter, you should be familiar with Microsoft Visual
Basic or C# and be comfortable with the following tasks:
Q Creating a Windows Forms or WPF application in Microsoft Visual Studio using
Visual Basic or C#
Q Adding namespaces and system class library references to a project
Q Writing to files and streams
Lesson 1: Drawing Graphics 221
Lesson 1: Drawing Graphics
You can use the .NET Framework to enhance the user interface by drawing lines, cir-
cles, and other shapes. With just a couple of lines of code, you can display these
graphics on a form or other Windows Forms control.
After this lesson, you will be able to:
Q Describe the members of the System.Drawing namespace
Q Control the location, size, and color of controls
Q Draw lines, empty shapes, and solid shapes
Q Customize pens and brushes to enhance graphics
Estimated lesson time: 60 minutes
The System.Drawing Namespace

The .NET Framework includes the System.Drawing namespace, which enables you to
create graphics from scratch or modify existing images. With the System.Drawing
namespace, you can do the following:
Q Add circles, lines, and other shapes to the user interface dynamically.
Q Create charts from scratch.
Q Edit and resize pictures.
Q Change the compression ratios of pictures saved to disk.
Q Crop or zoom pictures.
Q Add copyright logos or text to pictures.
This lesson focuses on drawing graphics. Lesson 2 covers working with images, and
Lesson 3 describes how to format text.
Table 6-1 lists the most important classes in the System.Drawing namespace, which
you can use to build objects used for creating and editing images.
Of these classes, you use Graphics the most because it provides methods for drawing
to the display device. The Pen class is used to draw lines and curves, while classes
derived from the abstract class Brush are used to fill the interiors of shapes. In addi-
tion, you should be familiar with the PictureBox class (in the System.Windows.Forms
namespace), which you can use in Windows Forms applications to display an image
as part of the user interface. The System.Drawing namespace includes the structures
shown in Table 6-2.
222 Chapter 6 Graphics
Table 6-1 System.Drawing Classes
Class Description
Bitmap Encapsulates a GDI+ (Graphical Device Interface) bitmap, which
consists of the pixel data for a graphics image and its attributes.
A Bitmap object is an object used to work with images defined by
pixel data. This is the class you use when you need to load or
save images.
Brush Classes derived from this abstract base class, described in the
section “How to Fill Shapes,” later in this lesson, define objects

used to fill the interiors of graphical shapes such as rectangles,
ellipses, pies, polygons, and paths.
Brushes Provides brushes for all the standard colors. This class cannot be
inherited. Use this class to avoid creating an instance of a Brush
class.
ColorConverter Converts colors from one data type to another. Access this class
through the TypeDescriptor.
ColorTranslator Translates colors to and from GDI+ Color structures. This class
cannot be inherited.
Font Defines a particular format for text, including font face, size, and
style attributes. This class cannot be inherited.
FontConverter Converts Font objects from one data type to another. Access the
FontConverter class through the TypeDescriptor object.
FontFamily Defines a group of type faces having a similar basic design and
certain variations in styles. This class cannot be inherited.
Graphics Encapsulates a GDI+ drawing surface. This class cannot be
inherited. You use this class anytime you need to draw lines,
draw shapes, or add graphical text to a control or image.
Icon Represents a Microsoft Windows icon, which is a small bitmap
image used to represent an object. Icons can be thought of as
transparent bitmaps, although their size is determined by the
system.
Lesson 1: Drawing Graphics 223
IconConverter Converts an Icon object from one data type to another. Access
this class through the TypeDescriptor object.
Image An abstract base class that provides functionality for the
Bitmap- and Metafile-descended classes.
ImageAnimator Animates an image that has time-based frames.
ImageConverter Converts Image objects from one data type to another.
Access this class through the TypeDescriptor object.

ImageFormat-
Converter
Converts colors from one data type to another. Access this class
through the TypeDescriptor object.
Pen Defines an object used to draw lines, curves, and arrows. This
class cannot be inherited.
Pens Provides pens for all the standard colors. This class cannot be
inherited. Use this class to avoid creating an instance of a Pen
class.
PointConverter Converts a Point object from one data type to another. Access
this class through the TypeDescriptor object.
Rectangle-
Converter
Converts rectangles from one data type to another. Access this
class through the TypeDescriptor object.
Region Describes the interior of a graphics shape composed of
rectangles and paths. This class cannot be inherited.
SizeConverter The SizeConverter class is used to convert from one data type to
another. Access this class through the TypeDescriptor object.
SolidBrush Defines a brush of a single color. Brushes are used to fill graphics
shapes, such as rectangles, ellipses, pies, polygons, and paths.
This class cannot be inherited.
StringFormat Encapsulates text layout information (such as alignment and
line spacing), display manipulations (such as ellipsis insertion
and national digit substitution), and OpenType features. This
class cannot be inherited.
Table 6-1 System.Drawing Classes
Class Description
224 Chapter 6 Graphics
SystemBrushes Each property of the SystemBrushes class is a SolidBrush object

that is the color of a Windows display element.
SystemColors Each property of the SystemColors class is a Color structure that is
the color of a Windows display element.
SystemFonts Specifies the fonts used to display text in Windows display
elements.
SystemIcons Each property of the SystemIcons class is an Icon object for
Windows systemwide icons. This class cannot be inherited.
SystemPens Each property of the SystemPens class is a Pen object that is the
color of a Windows display element and that has a width of 1.
TextureBrush Each property of the TextureBrush class is a Brush object that uses
an image to fill the interior of a shape. This class cannot be
inherited.
ToolboxBitmap-
Attribute
You can apply a ToolboxBitmapAttribute to a control so that
containers, such as the Form Designer in Visual Studio, can
retrieve an icon that represents the control. The bitmap for the
icon can be in a file by itself or embedded in the assembly that
contains the control.
The size of the bitmap that you embed in the control’s assembly
(or store in a separate file) should be 16 by 16. The GetImage
method of a ToolboxBitmapAttribute object can return the small
16-by-16 image or a large 32-by-32 image that it creates by scaling
the small image.
Table 6-2 System.Drawing Structures
Structure Description
CharacterRange Specifies a range of character positions within a string.
Color Represents a color.
Point Represents an ordered pair of integer x and y coordinates that
defines a point in a two-dimensional plane.

Table 6-1 System.Drawing Classes
Class Description
Lesson 1: Drawing Graphics 225
The most important of these structures—the structures you use most often—are Color,
Point, Rectangle, and Size.
How to Specify the Location and Size of Controls
One of the simplest and most common uses for the System.Drawing namespace is
specifying the location of controls in a Windows Forms application. This process can
be useful to create forms that dynamically adjust based on user input.
To specify a control’s location, create a new Point structure by specifying the coordi-
nates relative to the upper-left corner of the form, and use the Point to set the control’s
Location property. The related PointF structure accepts coordinates as floating points,
rather than integers, but PointF cannot be used to specify the location of graphical
user interface (GUI) controls. For example, to move a button to the upper-left corner
of a form, exactly 10 pixels from the top and left sides, you would use the following
code:
' VB
button1.Location = New Point(10, 10)

// C#
button1.Location = new Point(10, 10);
PointF Represents an ordered pair of floating-point x and y coordi-
nates that defines a point in a two-dimensional plane.
Rectangle Stores a set of four integers that represent the location and
size of a rectangle. For more advanced region functions, use a
Region object.
RectangleF Stores a set of four floating-point numbers that represent the
location and size of a rectangle. For more advanced region
functions, use a Region object.
Size Stores an ordered pair of integers, typically the width and

height of a rectangle.
SizeF Stores an ordered pair of floating-point numbers, typically
the width and height of a rectangle.
Table 6-2 System.Drawing Structures
Structure Description
226 Chapter 6 Graphics
NOTE Graphics Require a Windows Forms Application
Most of this book relies on Console applications for samples. However, this chapter uses Windows
Forms applications to display graphics easily.
As an alternative to using Point, you could perform the same function using the Left
and Top or Right and Bottom properties of a control. However, this requires two lines
of code, as the following example illustrates:
' VB
button1.Left = 10
button1.Top = 10

// C#
button1.Left = 10;
button1.Top = 10;
You can specify the size of a control just as simply as you specify the location. The
following code demonstrates how to specify the size using the Size class:
' VB
button1.Size = New Size(30, 30)

// C#
button1.Size = new Size(30, 30);
How to Specify the Color of Controls
You can specify a control’s color using the Color structure. The simplest way to specify
a color is to use one of the predefined properties located within System.Drawing.Color,
as the following example demonstrates:

' VB
Button1.ForeColor = Color.Red
Button1.BackColor = Color.Blue

// C#
button1.ForeColor = Color.Red;
button1.BackColor = Color.Blue;
If you need to specify a custom color, use the static Color.FromArgb method. The
method has several overloads, so you can specify the color by using a single byte, by
specifying the red, green, and blue levels individually, or by using other information.
The following example illustrates how to specify color by providing three integers, for
red, green, and blue:
Lesson 1: Drawing Graphics 227
' VB
Button1.ForeColor = Color.FromArgb(10, 200, 200)
Button1.BackColor = Color.FromArgb(200, 5, 5)

// C#
button1.ForeColor = Color.FromArgb(10, 200, 200);
button1.BackColor = Color.FromArgb(200, 5, 5);
How to Draw Lines and Shapes
To draw on a form or control, follow these high-level steps:
1. Create a Graphics object by calling the System.Windows.Forms.Control.Create-
Graphics method.
2. Create a Pen object.
3. Call a member of the Graphics class to draw on the form or control using the Pen.
Drawing begins with the System.Drawing.Graphics class. To create an instance of this
class, you typically call a control’s CreateGraphics method. Alternatively, as discussed
in Lesson 2, you can create a Graphics object based on an Image object if you want to
be able to save the picture as a file. Once you create the Graphics object, you can call

many methods to perform the drawing, including the following:
Q Clear Clears the entire drawing surface and fills it with a specified color.
Q DrawEllipse Draws an ellipse or circle defined by a bounding rectangle specified
by a pair of coordinates, a height, and a width. The ellipse touches the edges of
the bounding rectangle.
Q DrawIcon and DrawIconUnstretched Draws the image represented by the speci-
fied icon at the specified coordinates, with or without scaling the icon.
Q DrawImage, DrawImageUnscaled, and DrawImageUnscaledAndClipped Draws the
specified Image object at the specified location, with or without scaling or crop-
ping the image.
Q DrawLine Draws a line connecting the two points specified by the coordinate
pairs.
Q DrawLines Draws a series of line segments that connect an array of Point structures.
Q DrawPath Draws a series of connected lines and curves.
228 Chapter 6 Graphics
Q DrawPie Draws a pie shape defined by an ellipse specified by a coordinate
pair, a width, a height, and two radial lines. Note that the coordinates you
supply with DrawPie specify the upper-left corner of an imaginary rectangle
that would form the pie’s boundaries; the coordinates do not specify the pie’s
center.
Q DrawPolygon Draws a shape with three or more sides as defined by an array of
Point structures.
Q DrawRectangle Draws a rectangle or square specified by a coordinate pair, a
width, and a height.
Q DrawRectangles Draws a series of rectangles or squares specified by Rectangle
structures.
Q DrawString Draws the specified text string at the specified location with the
specified Brush and Font objects.
To use any of these methods, you must provide an instance of the Pen class. Typically,
you specify the color and width of the Pen class in pixels with the constructor. For

example, the following code draws a red line 7 pixels wide from the upper-left corner
(1, 1) to a point near the middle of the form (100, 100), as shown in Figure 6-1. To run
this code, create a Windows Forms application and add the code to a method that
runs in response to the form’s Paint event:
' VB
' Create a graphics object from the form
Dim g As Graphics = Me.CreateGraphics

' Create a pen object with which to draw
Dim p As Pen = New Pen(Color.Red, 7)

' Draw the line
g.DrawLine(p, 1, 1, 100, 100)

// C#
// Create a graphics object from the form
Graphics g = this.CreateGraphics();

// Create a pen object with which to draw
Pen p = new Pen(Color.Red, 7);

// Draw the line
g.DrawLine(p, 1, 1, 100, 100);
Lesson 1: Drawing Graphics 229
Figure 6-1 Use Graphics.DrawLine to create straight lines
Similarly, the following code draws a blue pie shape with a 60-degree angle, as shown
in Figure 6-2:
' VB
Dim g As Graphics = Me.CreateGraphics
Dim p As Pen = New Pen(Color.Blue, 3)


g.DrawPie(p, 1, 1, 100, 100, -30, 60)

// C#
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.Blue, 3);

g.DrawPie(p, 1, 1, 100, 100, -30, 60);
Figure 6-2 Use Graphics.DrawPie to create pie shapes
230 Chapter 6 Graphics
The Graphics.DrawLines, Graphics.DrawPolygon, and Graphics.DrawRectangles methods
accept arrays as parameters to allow you to create more complex shapes. For example,
the following code draws a purple, five-sided polygon, as shown in Figure 6-3:
' VB
Dim g As Graphics = Me.CreateGraphics
Dim p As Pen = New Pen(Color.MediumPurple, 2)

' Create an array of points
Dim points As Point() = New Point() {New Point(10, 10), _
New Point(10, 100), _
New Point(50, 65), _
New Point(100, 100), _
New Point(85, 40)}

' Draw a shape defined by the array of points
g.DrawPolygon(p, points)

// C#
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.MediumPurple, 2);


// Create an array of points
Point[] points = new Point[]
{new Point(10, 10),
new Point(10, 100),
new Point(50, 65),
new Point(100, 100),
new Point(85, 40)};

// Draw a shape defined by the array of points
g.DrawPolygon(p, points);
Figure 6-3 Use Graphics.DrawPolygon to create shapes made of multiple lines
Lesson 1: Drawing Graphics 231
NOTE Horizontal, Then Vertical
When you pass coordinates to any .NET Framework method, you pass the horizontal (x) coordinate
first, and then the vertical (y) coordinate second. In a 100-by-100 pixel image, (0,0) is the upper-left
corner, (100,0) is the upper-right corner, (0, 100) is the lower-left corner, and (100,100) is the
lower-right corner.
How to Customize Pens
Besides controlling the color and size of a pen, which are specified in the Pen con-
structor, you can also control the pattern and endcaps. The endcaps are the ends of
the line, and you can use them to create arrows and other special effects.
By default, pens draw solid lines. To draw a dotted line, create an instance of the Pen class,
and then set the Pen.DashStyle property to one of these values: DashStyle.Dash, Dash-
Style.DashDot, DashStyle.DashDotDot, DashStyle.Dot, or DashStyle.Solid. The following
code, which requires the System.Drawing.Drawing2D namespace, demonstrates each of
these pen styles and creates the result shown in Figure 6-4:
' VB
Dim g As Graphics = Me.CreateGraphics
Dim p As Pen = New Pen(Color.Red, 7)


p.DashStyle = DashStyle.Dot
g.DrawLine(p, 50, 25, 400, 25)

p.DashStyle = DashStyle.Dash
g.DrawLine(p, 50, 50, 400, 50)

p.DashStyle = DashStyle.DashDot
g.DrawLine(p, 50, 75, 400, 75)

p.DashStyle = DashStyle.DashDotDot
g.DrawLine(p, 50, 100, 400, 100)

p.DashStyle = DashStyle.Solid
g.DrawLine(p, 50, 125, 400, 125)

// C#
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.Red, 7);

p.DashStyle = DashStyle.Dot;
g.DrawLine(p, 50, 25, 400, 25);

p.DashStyle = DashStyle.Dash;
g.DrawLine(p, 50, 50, 400, 50);

232 Chapter 6 Graphics
p.DashStyle = DashStyle.DashDot;
g.DrawLine(p, 50, 75, 400, 75);


p.DashStyle = DashStyle.DashDotDot;
g.DrawLine(p, 50, 100, 400, 100);

p.DashStyle = DashStyle.Solid;
g.DrawLine(p, 50, 125, 400, 125);
Figure 6-4 The Pen class provides several dash styles
You can also use the Pen.DashOffset and Pen.DashPattern properties to define a custom
dash pattern.
To control the endcaps and create arrows or callouts, modify the Pen.StartCap and
Pen.EndCap properties using the LineCap enumeration. The following code demon-
strates most of the pen cap styles and creates the result shown in Figure 6-5:
' VB
Dim g As Graphics = Me.CreateGraphics
Dim p As Pen = New Pen(Color.Red, 10)

p.StartCap = LineCap.ArrowAnchor
p.EndCap = LineCap.DiamondAnchor
g.DrawLine(p, 50, 25, 400, 25)

p.StartCap = LineCap.SquareAnchor
p.EndCap = LineCap.Triangle
g.DrawLine(p, 50, 50, 400, 50)

p.StartCap = LineCap.Flat
p.EndCap = LineCap.Round
g.DrawLine(p, 50, 75, 400, 75)

p.StartCap = LineCap.RoundAnchor
p.EndCap = LineCap.Square
g.DrawLine(p, 50, 100, 400, 100)


// C#
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.Red, 10);
Lesson 1: Drawing Graphics 233

p.StartCap = LineCap.ArrowAnchor;
p.EndCap = LineCap.DiamondAnchor;
g.DrawLine(p, 50, 25, 400, 25);

p.StartCap = LineCap.SquareAnchor;
p.EndCap = LineCap.Triangle;
g.DrawLine(p, 50, 50, 400, 50);

p.StartCap = LineCap.Flat;
p.EndCap = LineCap.Round;
g.DrawLine(p, 50, 75, 400, 75);

p.StartCap = LineCap.RoundAnchor;
p.EndCap = LineCap.Square;
g.DrawLine(p, 50, 100, 400, 100);
Figure 6-5 The Pen class provides options for startcaps and endcaps
How to Fill Shapes
For most of the Draw methods, the Graphics class also has Fill methods that draw a
shape and fill in the contents. These methods work exactly like the Draw methods,
except they require an instance of the Brush class instead of the Pen class. The Brush
class is abstract, so you must instantiate one of the following child classes:
Q System.Drawing.Drawing2D.HatchBrush Defines a rectangular brush with a hatch
style, a foreground color, and a background color
Q System.Drawing.Drawing2D.LinearGradientBrush Encapsulates a brush with a lin-

ear gradient that provides a visually appealing, professional-looking fill
Q System.Drawing.Drawing2D.PathGradientBrush Provides similar functionality to
LinearGradientBrush; however, you can define a complex fill pattern that fades
between multiple points
Q System.Drawing.SolidBrush Defines a brush of a single color
Q System.Drawing.TextureBrush Defines a brush made from an image that can be
tiled across a shape, like a wallpaper design
234 Chapter 6 Graphics
For example, the following code draws a solid maroon, five-sided polygon, as shown
in Figure 6-6:
' VB
Dim g As Graphics = Me.CreateGraphics
Dim b As Brush = New SolidBrush(Color.Maroon)
Dim points As Point() = New Point() {New Point(10, 10), _
New Point(10, 100), _
New Point(50, 65), _
New Point(100, 100), _
New Point(85, 40)}

g.FillPolygon(b, points)

// C#
Graphics g = this.CreateGraphics();
Brush b = new SolidBrush(Color.Maroon);
Point[] points = new Point[]
{new Point(10, 10),
new Point(10, 100),
new Point(50, 65),
new Point(100, 100),
new Point(85, 40)};


g.FillPolygon(b, points);
Figure 6-6 Use the Brush class with the various Graphics.Fill methods to draw solid objects
You can draw filled objects with an outline by first calling the Graphics.Fill method
and then calling the Graphics.Draw method. For example, the following code draws a
polygon with an outline and a linear gradient fill pattern, as shown in Figure 6-7:
' VB
Dim g As Graphics = Me.CreateGraphics
Dim p As Pen = New Pen(Color.Maroon, 2)
Dim b As Brush = New LinearGradientBrush(New Point(1, 1), New Point(100, 100), _
Color.White, Color.Red)
Dim points As Point() = New Point() {New Point(10, 10), _
New Point(10, 100), _
New Point(50, 65), _
New Point(100, 100), _
New Point(85, 40)}

Lesson 1: Drawing Graphics 235
g.FillPolygon(b, points)
g.DrawPolygon(p, points)

// C#
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.Maroon, 2);
Brush b = new LinearGradientBrush(new Point(1,1), new Point(100,100),
Color.White, Color.Red);
Point[] points = new Point[]
{new Point(10, 10),
new Point(10, 100),
new Point(50, 65),

new Point(100, 100),
new Point(85, 40)};

g.FillPolygon(b, points);
g.DrawPolygon(p, points);
Figure 6-7 Combine Graphics.Fill and Graphics.Draw methods to create solid objects with outlines
You can use the same techniques to draw on controls, such as buttons or the
instances of the PictureBox class. If you need to fill an entire Graphics object with a sin-
gle color, call the Graphics.Clear method.
Lab: Create a Method to Draw a Pie Chart
In this lab, you will create a method to draw a pie chart, and then improve that method
to make the pie chart more visually appealing. If you encounter a problem completing an
exercise, the completed projects are available on the companion CD in the Code folder.
Exercise 1: Draw a Pie Chart
In this exercise, you will write a method that draws a pie chart given an array of data
and a Size structure. At this point, simple black lines will suffice.
1. Navigate to the \<InstallHome>\Chapter06\Lesson1\Exercise1\Partial folder and
open either the C# version or the Visual Basic .NET version of the solution file.
2. Examine the form. The form has a single PictureBox named chart that is bound to
all four sides of the form. Notice that the Paint event calls the Draw method.
236 Chapter 6 Graphics
3. Examine the Draw method that takes no parameters. This method includes
sample data that will be passed as parameters to the drawPieChart method you
will complete. Notice that the drawPieChart method returns an Image object,
which is used to define the chart PictureBox.
4. Examine the PieChartElement class. This simple class contains information to
describe a single section of your pie chart.
5. Examine the drawPieChart method in the Form1 file. It receives two parameters:
an ArrayList containing only PieChartElement objects, and a Size structure.
6. Complete the drawPieChart method. First, define a Bitmap object to be returned,

create a Graphics object from the Bitmap object, and then return the Bitmap
object. For example, the following code would work:
' VB
Dim bm As Bitmap = New Bitmap(s.Width, s.Height)
Dim g As Graphics = Graphics.FromImage(bm)

' TODO: Draw pie chart in g
Return bm

// C#
Bitmap bm = new Bitmap(s.Width, s.Height);
Graphics g = Graphics.FromImage(bm);

// TODO: Draw pie chart in g
return bm;
7. At this point, the project compiles, but if you run the application no pie chart is
drawn. Before you can create a pie chart from the PieChartElement objects in the
ArrayList, you must determine how many degrees each element uses. To do that,
in the drawPieChart method you must calculate the total of the value properties
of all the PieChartElement objects. For example, the following code would work:
' VB
' Calculate total value of all rows
Dim total As Single = 0

For Each e As PieChartElement In elements
If e.value < 0 Then
Throw New ArgumentException("All elements must have positive values")
End If
total += e.value
Next


// C#
// Calculate total value of all rows
float total = 0;

Lesson 1: Drawing Graphics 237
foreach (PieChartElement e in elements)
{
if (e.value < 0)
{
throw new ArgumentException("All elements must have positive values");
}
total += e.value;
}
8. Now you should define the rectangle that the pie chart will consume based on
the Size structure passed to the drawPieChart method as a parameter. The follow-
ing code would work, and it provides a sufficient buffer on all sides of the image:
' VB
' Define the rectangle that the pie chart will use
Dim rect As Rectangle = New Rectangle(1, 1, s.Width - 2, s.Height - 2)

// C#
// Define the rectangle that the pie chart will use
Rectangle rect = new Rectangle(1, 1, s.Width - 2, s.Height - 2);
9. Next, define a Pen object with which to draw the pie chart. This can be a simple,
black, one-pixel pen, defined with the following code:
' VB
Dim p As Pen = New Pen(Color.Black, 1)

// C#

Pen p = new Pen(Color.Black, 1);
10. Finally, create a foreach loop that calculates the degrees for each pie chart section,
and draws the pie chart sections. There are many ways to do this, such as the fol-
lowing code:
' VB
' Draw the first section at 0 degrees
Dim startAngle As Single = 0

' Draw each of the pie shapes
For Each e As PieChartElement In elements
' Calculate the degrees that this section will consume
' based on the percentage of the total
Dim sweepAngle As Single = (e.value / total) * 360

' Draw the pie shape
g.DrawPie(p, rect, startAngle, sweepAngle)

' Calculate the angle for the next pie shape by adding
' the current shape's degrees to the previous total.
startAngle += sweepAngle
Next

238 Chapter 6 Graphics
// C#
// Draw the first section at 0 degrees
float startAngle = 0;

// Draw each of the pie shapes
foreach (PieChartElement e in elements)
{

// Calculate the degrees that this section will consume
// based on the percentage of the total
float sweepAngle = (e.value / total) * 360;

// Draw the pie shape
g.DrawPie(p, rect, startAngle, sweepAngle);

// Calculate the angle for the next pie shape by adding
// the current shape's degrees to the previous total.
startAngle += sweepAngle;
}
11. Build the application and fix any errors; then run the application. Resize the
form, and notice that the pie chart is automatically resized; the Paint event calls
the Draw method when you resize the form.
Exercise 2: Improve the Appearance of the Pie Chart
In this exercise, you will improve the project presented in Exercise 1 to make the pie
chart more visually appealing. Specifically, you fill in each section with a different
color and enable anti-aliasing to smooth the lines.
1. Navigate to the \<InstallHome>\Chapter06\Lesson1\Exercise2\Partial folder,
and open either the C# version or the Visual Basic version of the PieChart project.
Alternatively, you can continue working from the project you created in Exercise 1.
2. First, at the beginning of the drawPieChart method, create an array containing
the colors you want to use in your pie chart. You will assign the colors sequen-
tially, so do not place similar colors after each other. For the sake of simplicity,
throw an exception if the pie chart has more elements than you have colors in
your array. For example:
' VB
Dim colors As Color() = {Color.Red, Color.Orange, Color.Yellow, Color.Green, _
Color.Blue, Color.Indigo, Color.Violet, Color.DarkRed, Color.DarkOrange, _
Color.DarkSalmon, Color.DarkGreen, Color.DarkBlue, Color.Lavender, _

Color.LightBlue, Color.Coral}

If elements.Count > colors.Length Then
Throw New ArgumentException("Pie chart must have " + _
colors.Length.ToString() + " or fewer elements")
End If

×