Preface
This article overviews WPF's graphics capabilities, including two-dimensional and three-dimensional shapes, fonts, and animations. The writer would like to stress that this article is for beginners. The reason why I am writing this article is because WPF integrates drawing and animation features that were previously available only in special libraries (such as Microsoft GDI+ and DirectX). The graphics system in WPF is designed for your computer graphics hardware to reduce the load on the CPU, and in many cases, speeds up graphics rendering. So taking WPF for what it is, it is actually a remarkable technology that, apparently, can read and assess what your machine's graphics capabilities are via the machine's video interface card. Moreover, WPF graphics uses a resolution-independent measurement in units to make applications more uniform and portable across devices. For instance, the size properties of elements in WPF are measured in resolution-independent pixels, where one pixel represents 1/96 of an inch--but this depends on the computer's DPI (dots per inch) setting. The graphics engine determines the correct pixel count so that all users see elements of the same size on all devices. To emphasize the importance of graphics sketching, I also introduce the Microsoft Blend SDK version 4.
Graphic elements are rendered on screen using a vector-based system in which calculations determine how to size and scale each element in order to prevent an oversized element against a regular-size foreground. The basic 2-D shapes are Lines, Rectangles, and Ellipses. WPF, as we all know, has controls that can be used to create custom shapes or curves. Brushes can be used to fill an element with solid colors, complex patterns, images, and even videos.
Tell Me What XAML is
In Windows Presentation Foundation, the screens are built with a dialect of XML called Extensible Application Markup Language (XAML). XML is data centric and is viewed as a technology in its own right. Data on certain web pages or a Web Service request (response message) is in the form of an XML document. Any data (any alphanumeric character) is tagged, as the rules for XML are very strict. That is, controls, images, or any item that is marked up on a page via HTML comprises the presentation content. Alphabetic letters or numbers are separately tagged via XML. The idea is to separate the presentation content on a web page from the data. This outputs a more dazzling-looking page. XAML is more declarative than imperative. By declarative, I mean that a control is specified as an XML element, with attributes and sub-elements to describe what the control will look like. You do not have to be concerned with how this is done because when you tell WPF what you want, it will figure out how to build the controls (instantiating objects and assigning properties) under the hood. This parallels dragging and dropping a control onto a Windows Form. The partial classes enable code to be generated, where the developer is only responsible for writing the event handler code. In addition, the designer is split between a graphical design surface on top and XAML on the bottom. The designer works the same as Windows Forms in that you can drag and drop controls onto it and edit them in the Properties window. But XAML is new, and we therefore must take a close look at XAML and define some terms that are used in WPF.
Examining XAML
In Windows Forms, everything translates directly into code. However, WPF translates its user interface to XAML, which gets compiled into code later. This is a key distinction: XAML compiles into a binary form called BAML. At this point, however, it is not necessary to go into a description of BAML. Just note that when working in the UI designer for a WPF project, VS2008 produces XAML, instead of code for all UI elements.
<Window x:Class="MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
</Grid>
</Window>
The XAML defines a window with a title, dimensions, and an empty grid. A later section on layout explains the grid. Because it's XML, you also have namespaces: xmlns
and xmlns:x
. Windows are often associated with a code-behind file, which is C#. But where does the C# code come into play? WPF uses events, just like Windows Forms, so you need a place for the handlers to go, which is the code-behind.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
Notice that the Window1
class in the code-behind is partial
and that its constructor calls InitializeComponent
. In Windows Forms, the InititalizeComponent
was in a separate file that you could get to. However, WPF generates InitializeComponent
from the XAML. You see, WPF will ensure that the XAML creates a partial class named Window1
with an InitializeComponent
method, and then C# will combine and compile the partials. If you get an error message that underlines InitializeMethod
, then drag your mouse over that underline noting the error. A box should appear that when clicked, gives you the option to generate a "stub method" to correct the error.
Controls in XAML
Many people will use the drag-and-drop capabilities of the WPF designer to build their UIs, but others will want to work directly in XAML. To try out the designer, drag and drop a Label
control onto the window in the designer. If you have the split window open, you'll see the XAML for the Label
come into view. You can see the Label
control in the XAML code and how the text inside of the Label
tag has been changed. There are also attributes on the Label
that match properties that you'll see in the Properties window. The Name
attribute is the variable name you use in code to access this label if you need to, and VerticalAlignment
describes how this control will align within its parent element, which means that this Label
will align inside the top border of the grid. The Margin
comes later when talking about layout (it means that the top, left, right, and bottom borders are the specified distance from the containing control, which is the Grid
). Notice that the Content
property matches the label text, but the XAML doesn't show a Content
property. The XAML we used was a shortcut for the following:
<Label Height="28" Margin="80,94,78,0"
Name="label1" VerticalAlignment="Top">
<Label.Content>
What the Heck is XAML?
</Label.Content>
</Label>
Output:
If you want to use text only, which is the most typical content, you don't need to wrap the text in the property-specific content element. However, one of the cool things about XAML controls is their composability. Whether it is a label, button, text box, or any other type of control, you can add any type of content to them that you want. You can put only one item inside of the Content
element, but that one element can be a layout control that can hold many controls.
Managing Layout
One of the subjects in the previous section was how WPF determined where the Label
control should appear on the page, its size, and its relationship to other controls. While Windows Forms applications have absolute positioning and layout support via anchoring and docking, WPF is more sophisticated and has more options. For WPF, you need to know about control alignment and sizing, borders and margins, and layout controls for defining the relationship of the containing controls and where they appear. With WPF controls, you can control their alignment and size. You can also manage their content, borders, and margins, which are often referred to as the box model. The default behavior of a WPF control is to stretch to fill its contents. If you are using a ListBox
or Grid
, filling the entire area might be the desired appearance, but you might not want this to happen with Button
or Label
controls. The following Label
control demonstrates stretching behavior:
<Label Name="label1" Background="AliceBlue">
What the Heck is XAML?
</Label>
This Label
doesn't have any attributes that specify its size or position, so the default is to stretch. In any event, a common way to lay out controls is for them to be in-line horizontally or vertically. You can use the StackPanel
layout control to accomplish this. Here's an example:
<StackPanel Orientation="Horizontal">
<Label>One</Label>
<Label>After</Label>
<Label>the Other</Label>
</StackPanel>
You can add numerous items to the StackPanel
, as you saw previously with the Label
controls, and it will line them up. The XAML code below shows what this looks like. The example sets the Orientation
property to Horizontal
, but Orientation
will default to Vertical
if you omit it. The UniformGrid
control divides the size of each cell evenly for all of its controls. The following example shows how this works:
<UniformGrid Height="100" Name="uniformGrid1" Width="200">
<Label>O</Label>
<Label>X</Label>
<Label>O</Label>
<Label>X</Label>
<Label>O</Label>
<Label>X</Label>
<Label>O</Label>
<Label>X</Label>
<Label>O</Label>
</UniformGrid>
Because there are nine items, the grid will look like a tic-tac-toe board. If you need more explicit control of the grid layout, you should use the Grid layout control. So another layout arrangement you'll need is to place items in tabular format with rows and columns, which is the role of the Grid layout. That Grid
was empty, but you'll often want to create rows and columns. The code below shows you how to use a Grid
:
<Window x:Class="Main.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="400">
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3"
HorizontalAlignment="Center">
Grid Facts
</Label>
<Label Grid.Row="1" Grid.Column="0">
Width="125"
</Label>
<Label Grid.Row="1" Grid.Column="1">
Absolute Column Width
</Label>
<Label Grid.Row="1" Grid.Column="2">
Grid.Column
</Label>
<Label Grid.Row="2" Grid.Column="0">
Width="2*"
</Label>
<Label Grid.Row="2" Grid.Column="1">
Proportional Spacing
</Label>
<Label Grid.Row="2" Grid.Column="2">
Grid.Column
</Label>
<Label Grid.Row="3" Grid.Column="0">
Width="Auto"
</Label>
<Label Grid.Row="3" Grid.Column="1">
Fill Remaining Space
</Label>
<Label Grid.Row="3" Grid.Column="2">
Grid.Column
</Label>
<Label Grid.Row="4" Grid.Column="0">
Height="25"
</Label>
<Label Grid.Row="4" Grid.Column="1">
Absolute Row Height
</Label>
<Label Grid.Row="4" Grid.Column="2">
Grid.Row
</Label>
<Label Grid.Row="5" Grid.Column="0">
Grid.ColumnSpan="3"
</Label>
<Label Grid.Row="5" Grid.Column="1">
Cover 3 Columns
</Label>
<Label Grid.Row="5" Grid.Column="2">
Control Attribute
</Label>
</Grid>
</Window>
The first two items to notice in this code are Grid.ColumnDefinitions
and Grid.RowDefinitions
, which define the columns and rows, respectively. Combined with the Label
controls, the code below shows grid lines so that you can see the effects of sizing on rows and columns. Here's the line that makes this happen:
<Grid ShowGridLines="True">
You can use three settings to control the size of columns: absolute, proportional, and auto fill. Here is how they are used:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
Absolute sets an explicit width, and Auto fills in the rest of the width of the Grid layout's containing control. Proportional is a little different because it is proportional to the size of the other controls. The second column in the preceding example is twice the current average size of a column. Therefore, if the width of the grid's container is 400 and there are three columns, the average size of a column is approximately 133. Because the proportional coefficient is 2, the width of the second column is 2 x 133 = 266. You can use absolute, proportional, and auto-fill spacing on the Height
property of RowDefinition
elements, too. After you've defined the columns and rows, you must specify which column and row that controls go into. This example uses all Label
controls, but you can put any WPF control into the grid. Here's the control for the first column of the second row:
<Label Grid.Row="1" Grid.Column="0">
Width="125"
</Label>
See how the attributes Grid.Row
and Grid.Column
reference the row and column to put this control into. You can look at each of these controls and see how they appear. The first row has a single Label
that spans all columns of the Grid
, shown here:
<Label Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3"
HorizontalAlignment="Center">
Grid Stuff
</Label>
Notice the Grid.ColumnSpan
, which means that this control covers all three columns in the grid. If you need a control to cover multiple rows, you can use Grid.RowSpan
the same way. You can also set the horizontal alignment of the content with HorizontalAlignment
, or set the vertical alignment with VerticalAlignment
. With IntelliSense and auto-formatting in VS2008, it's a lot easier. One useful feature is whenever a block of XAML gets out of whack, you can highlight the block and press Ctrl+K+F to auto-format. If you don't like the default auto-format, you can change it yourself. Just select Tools, Options, Text Editor, and then select the XAML branch. You'll notice a few sub-branches that give you many options for how to format the XAML. If you've been using Windows Forms and have grown accustomed to the docking layout, WPF keeps you in your comfort zone with the DockPanel
. You can use the DockPanel
to position controls onto the top, left, bottom, right, and center of the client area. Here's an example:
<DockPanel>
<Label DockPanel.Dock="Top"
Background="CornflowerBlue">Top</Label>
<Label DockPanel.Dock="Bottom"
Background="Fuchsia">Bottom</Label>
<Label DockPanel.Dock="Left">Left</Label>
<Label DockPanel.Dock="Right">Right</Label>
<Label Background="Chartreuse">Center</Label>
</DockPanel>
Each control, except Center, in the DockPanel
has its DockPanel.Dock
set to the side of the client area it occupies. Controls, such as Center, without DockPanel.Dock
will fill in the remaining space. The image shows what this looks like. Background colors show what space is occupied by each control. Not too good but not bad. Top and Bottom span the width of the client area because they are the first controls entered. Left and Right occupy the remaining space. If Right had been placed in the listing before Bottom, it would have extended downward to the bottom of the client area, and Bottom would have stopped at Right's left border. The concept of managing the layout is sort of similar to web page design, the HTML (markup) places the presentation content within the borders of the web page that loads within the frame of the web browser. In WPF, we are merely managing the layout that will determine where either data or other controls can be placed, etc.
So Where Are We Now?
Let's Start with Fonts
This section of code introduces how to control fonts by modifying the font properties of a TextBlock
control in XAML code. The XAML code shows how to use TextBlock
s and how to change the properties to control the appearance of the displayed text. The manipulations shown at this point can also be applied to other text-based controls such as a TextBox
.
<Window x:Class="UsingFonts.UsingFontsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="UsingFonts" Height="120" Width="400">
<StackPanel>
<TextBlock FontFamily="Arial" FontSize="12"
FontWeight="Bold">
Arial 12 point bold.</TextBlock>
<TextBlock FontFamily="Times New Roman">
Times New Roman plain, default size.</TextBlock>
<TextBlock FontFamily="Courier New" FontSize="16"
FontStyle="Italic" FontWeight="Bold">
Courier New 16 point bold and italic.
</TextBlock>
<TextBlock>
<TextBlock.TextDecorations>
<TextDecoration Location="Overline" />
<TextDecoration Location="Baseline" />
</TextBlock.TextDecorations>
Default font with overline and
baseline.
</TextBlock>
<TextBlock>
<TextBlock.TextDecorations>
<TextDecoration Location="Strikethrough" />
<TextDecoration Location="Underline" />
</TextBlock.TextDecorations>
Default font with strikethrough and underline.
</TextBlock>
</StackPanel>
</Window>
The code-behind file is standard, as there are no event handlers, or more importantly, no RoutedEvent
s.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace UsingFonts
{
public partial class UsingFontsWindow : Window
{
public UsingFontsWindow()
{
InitializeComponent();
}
}
}
Upon building these files that comprise the Solution container, we get this output:
With this output, we can see why it works, but we should know how it works. The text that you want to display in the TextBlock
is placed between the TextBlock
tags. The FontFamily
property defines the font of the displayed text. This property can be set to any font. The lines define (that separate the TextBlock
fonts) to be Arial, Times New Roman, and Courier New, respectively. The FontSize
property defines the text size measured in points. When no FontSize
is specified, the property is set to the system's default value. TextBlock
s have various properties to further modify the font. The FontWeight
property can be set to bold to make the font thicker. This property can be set either to a numeric value (1-999) or to a predefined descriptive value--such as Light
or UltraBold
--to define the thickness of the text. You can use the FontStyle
property to make the text Italic
or Oblique
(which is a more emphasized italic). Finally, you can also define TextDecoration
s for a TextBlock
to draw a horizontal line through the text. Overline
and Baseline
, shown in the fourth TextBlock
, create lines above and below the text, respectively.
WPF has several built-in shapes. The example XAML code below will demonstrate how to display Line
s, Rectangle
s, and Ellipse
s. Examine the XAML code:
<Window x:Class="BasicShapes.BasicShapesWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BasicShapes" Height="200" Width="500">
<Canvas>
<Rectangle Canvas.Left="90" Canvas.Top="30"
Width="150" Height="90"
Fill="Blue"/>
<Line X1="90" Y1="30" X2="110"
Y2="40" Stroke="Black" />
<Line X1="90" Y1="120" X2="110"
Y2="130" Stroke="Black" />
<Line X1="240" Y1="30" X2="260"
Y2="40" Stroke="Black" />
<Line X1="240" Y1="120" X2="260"
Y2="130" Stroke="Black" />
<Rectangle Canvas.Left="110" Canvas.Top="40"
Width="150" Height="90"
Stroke="Black" />
<Ellipse Canvas.Left="280" Canvas.Top="75"
Width="100" Height="50" Fill="Red" />
<Line X1="380" Y1="55" X2="380"
Y2="100" Stroke="Black" />
<Line X1="280" Y1="55" X2="280"
Y2="100" Stroke="Black" />
<Ellipse Canvas.Left="280" Canvas.Top="30"
Width="100" Height="50"
Stroke="Black" />
</Canvas>
</Window>
For the sake of being complete, here is the standard code-behind file that is placed here (not to fill the space up, but to exemplify the class construction of BasicShapes
):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BasicShapes
{
public partial class BasicShapesWindow : Window
{
public BasicShapesWindow()
{
InitializeComponent();
}
}
}
This XAML code outputs some basic shapes:
Notice that we used the Rectangle
element to create a filled rectangle in the window. Also notice that the layout control is a Canvas
allowing us to use coordinates to position the shapes. To specify the upper-left corner of the Rectangle
, we set the attached properties Canvas.Left
and Canvas.Top
to 90 and 30, respectively. We then set the Width
and Height
properties to 150 and 90, respectively, to specify the size. To define the Rectangle
's color, we use the Fill
property.
Transforms: A Couple of Vector-Based Drawings using WPF
A transform can be applied to any element to reposition or reorient the graphic. There are four types of transforms: TranslateTransform
, RotateTransform
, SkewTransform
, and ScaleTransform
. A TranslateTransform
moves an object to another location. A RotateTransform
rotates the object around a point and by a specified RotationAngle
. A SkewTransform
shears (or skews) the object. A ScaleTransform
scales the object's x and y coordinate points by different specified amounts. A star shape is a polygon. If we want to draw a star, we use the Polygon
element and use RotateTransform
s to create a circle of randomly colored stars. Notice that we use the word random. This is the class used to generate random numbers, and therefore uses the same methods. The Points
property of the Polygon
in this example is defined in a new syntax. Here is the XAML:
<Window x:Class="DrawStars.DrawStarsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DrawStars" Height="330"
Width="330" Name="DrawStars">
<Canvas Name="mainCanvas">
<Polygon Name="star" Fill="Green"
Points="205,150 217,186 259,186
223,204 233,246 205,222 177,246
187,204 151,186 193,186" />
</Canvas>
</Window>
And here is the code-behind file that uses the Random
class of the System
namespace to generate the random number of coordinates. This, in combination with rotating the stars, creates a pretty nice image on the user interface:
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace DrawStars
{
public partial class DrawStarsWindow : Window
{
public DrawStarsWindow()
{
InitializeComponent();
Random random = new Random();
for ( int count = 0; count < 18; count++ )
{
Polygon newStar = new Polygon();
newStar.Points = star.Points;
byte[] colorValues = new byte[ 4 ];
random.NextBytes( colorValues );
newStar.Fill = new SolidColorBrush( Color.FromArgb(
colorValues[ 0 ], colorValues[ 1 ], colorValues[ 2 ],
colorValues[ 3 ] ) );
RotateTransform rotate =
new RotateTransform( count * 20, 150, 150 );
newStar.RenderTransform = rotate;
mainCanvas.Children.Add( newStar );
}
}
}
}
Here is the output:
Here is the XAML code that was generated after (using Expression Blend SDK: Microsoft vector-based graphics secret weapon) I drew an apple with a bite taken out of it. The purpose of this example is to show what can be imported to Visual Studio 2010 (2008) after gaining some experience using the WPF Sketch Flow application utility:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication2.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="447" Height="379">
<Grid x:Name="LayoutRoot">
<Canvas x:Name="L5end" HorizontalAlignment="Left"
Height="608" UseLayoutRounding="False"
VerticalAlignment="Top" Width="786">
<Canvas x:Name="Finished" Height="217.264"
Canvas.Left="78" Canvas.Top="34"
Width="265">
<Path Data="F1M378.744,178.918C377.298,179.752,375.053,180.286,
374.475,182.037L374.475,182.037C374.445,182.125,374.421,182.216,374.4,
182.314L374.4,182.314C373.904,184.608,376.707,185.631,378.275,
186.06L378.275,186.06C380.545,186.687,381.509,187.812,382.746,
189.742L382.746,189.742C383.811,191.404,385.122,192.872,386.217,
194.51L386.217,194.51C387.347,196.197,388.19,198.056,389.224,
199.802L389.224,199.802C391.193,203.13,392.886,206.579,394.803,
209.932L394.803,209.932C395.579,211.291,399.811,221.153,402.461,
219.625L402.461,219.625C406.568,217.253,396.952,177.703,382.98,
177.7L382.98,177.7C381.606,177.7,380.193,178.081,378.744,178.918"
Height="42.085" Canvas.Left="90.99"
Stretch="Fill" Canvas.Top="2.166" Width="29.075">
<Path.Fill>
<LinearGradientBrush EndPoint="0.533,0.52" StartPoint="0.783,0.422">
<GradientStop Color="#FFE2BB8F" Offset="0"/>
<GradientStop Color="#FF946C28" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
<Path Data="M374.4746,182.0371C374.4456,182.1241,
374.4206,182.2161,374.4006,182.3131C373.9046,184.6071,376.7066,
185.6311,378.2756,186.0601C380.5446,186.6871,381.5086,187.8111,
382.7456,189.7421C383.8116,191.4031,385.1216,192.8721,386.2166,
194.5101C387.3476,196.1971,388.1896,198.0571,389.2236,
199.8031C391.1926,203.1301,392.8856,206.5791,394.8026,
209.9321C395.5786,211.2911,399.8116,221.1531,402.4606,
219.6241C406.9716,217.0201,394.9316,169.5711,378.7446,
178.9181C377.2986,179.7521,375.0536,180.2861,374.4746,182.0371z"
Height="42.568" Canvas.Left="90.749"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF231F20"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="1.925"
Width="29.558"/>
<Path Data="F1M404.306,217.707C407.38,209.691,417.496,
204.789,425.95,205.555L425.95,205.555C437.2,206.569,
454.855,198.851,452.374,184.103L452.374,184.103C451.374,
178.159,447.041,175.532,441.349,175.534L441.349,
175.534C426.333,175.536,401.876,193.818,404.306,217.707"
Height="42.173" Canvas.Left="120.786"
Stretch="Fill" Canvas.Top="0" Width="48.472">
<Path.Fill>
<RadialGradientBrush Center="0.505,0.34"
GradientOrigin="0.657,0.219"
RadiusY="-0.653" RadiusX="-0.568">
<GradientStop Color="#FFC7C923" Offset="0"/>
<GradientStop Color="#FF8B7E14" Offset="1"/>
</RadialGradientBrush>
</Path.Fill>
</Path>
<Path Data="M404.3057,217.7065C400.9537,184.7615,448.7357,
162.4805,452.3737,184.1025C454.8547,198.8515,
437.2007,206.5685,425.9507,205.5545C417.4957,204.7895,
407.3807,209.6915,404.3057,217.7065z"
Height="42.657" Canvas.Left="120.544"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF231F20"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="-0.242"
Width="48.956"/>
<Path Data="M405.3633,213.7773C410.4833,197.0653,428.4073,
186.0543,445.6303,187.5053C446.3673,187.3603,
447.1333,187.4273,447.9033,187.6023"
Height="26.884" Canvas.Left="121.77"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF696A6C"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="11.602"
Width="43.024"/>
<Path Data="M411.5537,202.1333C413.5587,198.2793,415.6577,
194.3313,417.7447,190.4843"
Height="12.133" Canvas.Left="127.96"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF696A6C"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="14.709"
Width="6.675"/>
<Path Data="M421.9453,193.3672C423.5163,189.2672,
425.9853,185.3902,428.9773,182.3852"
Height="11.466" Canvas.Left="138.352"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF696A6C"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="6.61"
Width="7.516"/>
<Path Data="M433.292,188.6606C436.084,185.3616,
439.27,182.2546,442.592,179.6016"
Height="9.543" Canvas.Left="149.698"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF696A6C"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="3.826"
Width="9.784"/>
<Path Data="M412.6387,200.8149C416.3847,198.8229,420.7387,
198.9059,424.1097,201.1119"
Height="2.21" Canvas.Left="129.045"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF696A6C"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="23.61"
Width="11.955"/>
<Path Data="M422.8809,192.5947C427.4629,190.5367,
432.1079,191.6157,435.7489,195.3117"
Height="4.233" Canvas.Left="139.287"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF696A6C"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="15.787"
Width="13.352"/>
<Path Data="M436.2148,188.1265C440.3188,188.9795,
444.2928,191.0945,447.2158,193.9955"
Height="6.353" Canvas.Left="152.621"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF696A6C"
StrokeThickness="0.484" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="12.351"
Width="11.485"/>
<Path Data="M441.377,264.6914L501.314,218.8584"
Height="48.833" Canvas.Left="156.525"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF231F20"
StrokeThickness="3" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="41.825"
Width="62.937"/>
<Path Data="M517.5771,206.4209L501.8181,233.3119L500.0971,
219.7879L487.4971,214.5849L517.5771,206.4209z"
Fill="#FF231F20" Height="27.891"
Canvas.Left="203.645" StrokeStartLineCap="Flat"
Stretch="Fill" StrokeEndLineCap="Flat"
Stroke="#FF231F20" StrokeThickness="1"
StrokeMiterLimit="4" StrokeLineJoin="Miter"
Canvas.Top="30.387" Width="31.08"/>
<Path Data="F1M325.727,230.356C336.728,224.856,343.94,
231.892,337.402,241.917L337.402,241.917C349.17,
239.302,349.074,251.2,343.324,256.7L343.324,
256.7C370.092,279.401,341.761,307.732,325.198,
297.916L325.198,297.916C329.121,309.475,314.163,
314.461,306.04,304.955L306.04,304.955C306.04,328.955,
323.959,337.931,333.224,362.145L333.224,362.145C343.284,
388.44,381.283,394.823,397.783,380.823L397.783,
380.823C422.676,393.95,457.7,387.539,469.596,
356.035L469.596,356.035C483.093,320.289,
506.383,291.69,499.227,264.856L499.227,
264.856C491.227,234.856,471.227,190.856,400.728,
215.356L400.728,215.356C387.198,210.007,375.898,
207.777,366.402,207.777L366.402,207.777C345.72,
207.777,333.609,218.362,325.727,230.356"
Height="180.277" Canvas.Left="22.688"
Stretch="Fill" Canvas.Top="32.243"
Width="194.523">
<Path.Fill>
<RadialGradientBrush Center="0.674,0.261"
GradientOrigin="0.674,0.261"
RadiusY="-0.408" RadiusX="-0.378">
<GradientStop Color="#FFDF785E" Offset="0"/>
<GradientStop
Color="sc#1, 0.6877536, 0.101908535, 0.0670531541"
Offset="0.73030436038970947"/>
<GradientStop Color="#FFD12229"
Offset="1"/>
</RadialGradientBrush>
</Path.Fill>
</Path>
<Path Data="M499.2275,264.856C506.3825,291.69,483.0925,320.289,
469.5955,356.035C457.7005,387.539,422.6755,393.95,
397.7835,380.823C381.2835,394.823,343.2845,388.439,
333.2245,362.146C323.9585,337.931,306.0405,328.955,
306.0405,304.955C314.1635,314.461,329.1215,309.475,
325.1985,297.916C341.7605,307.732,370.0915,279.401,
343.3235,256.7C349.0735,251.2,349.1705,239.301,337.4025,
241.917C343.9405,231.892,336.7275,224.856,325.7275,
230.356C337.2275,212.856,357.7275,198.356,400.7275,
215.356C471.2275,190.856,491.2275,234.856,499.2275,
264.856z"
Height="181.277" Canvas.Left="22.189"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF5D5E60"
StrokeThickness="1" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="31.743"
Width="195.522"/>
<Path Data="M348.7686,327.2012C369.3546,321.7742,365.0376,
343.4692,365.0376,343.4692"
Height="18.139" Canvas.Left="64.917"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF231F20"
StrokeThickness="1" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="150.296"
Width="17.646"/>
<Path Data="M316.7446,364.0381L362.4076,329.1181"
Height="37.92" Canvas.Left="31.893"
StrokeStartLineCap="Flat" Stretch="Fill"
StrokeEndLineCap="Flat" Stroke="#FF231F20"
StrokeThickness="3" StrokeMiterLimit="4"
StrokeLineJoin="Miter" Canvas.Top="152.085"
Width="48.663"/>
<Path Data="M303.4497,361.2314L304.1217,361.3734L315.8637,
362.8864L295.8837,378.1654L283.3517,
376.6004L303.4497,361.2314z"
Fill="#FF231F20" Height="17.934"
Canvas.Left="-0.5" StrokeStartLineCap="Flat"
Stretch="Fill" StrokeEndLineCap="Flat"
Stroke="#FF231F20" StrokeThickness="1"
StrokeMiterLimit="4" StrokeLineJoin="Miter"
Canvas.Top="185.198" Width="33.512"/>
<Path Data="M295.7378,392.7979L297.6918,380.5289L317.6728,
365.2509C316.5628,369.1899,315.9618,373.3039,
315.7778,377.4739L295.7378,392.7979z"
Fill="#FF231F20" Height="28.547"
Canvas.Left="11.886" StrokeStartLineCap="Flat"
Stretch="Fill" StrokeEndLineCap="Flat"
Stroke="#FF231F20" StrokeThickness="1"
StrokeMiterLimit="4" StrokeLineJoin="Miter"
Canvas.Top="189.217" Width="22.935"/>
</Canvas>
</Canvas>
</Grid>
</Window>
Copy and paste this XAML into your Visual Studio IDE window for the XAML code. Here is what you get:
References
- The MSDN Library
- Deitel Associates