The final basic XAML
elements used to design a static (i.e., nonmoving) UI are
brushes. A brush is used just like a "real" brush—you can paint with it.
However, Silverlight brushes offer more: you can paint with color, you can
paint gradients, you can paint images, and you can even paint
videos.
Brushes can be used as alternatives to attributes such as Background, Fill, and
Stroke. However, you need to alter your syntax a bit. Instead of
using the attribute, you use a subelement, <ElementYouWantToBrush.OldAttribute>.
For example, filling a rectangle would look as follows:
<Rectangle>
<Rectangle.Fill>
<!-- brushes go here -->
</Rectangle.Fill>
</Rectangle>
The "easiest" brush is called SolidColorBrush
because it uses only one solid color, and there are no changes
within the color or gradients. Actually, when using attributes such as
Background,
Fill, or Stroke as we have done so far in this book, we
were implicitly using a SolidColorBrush. However, the
alternative syntax works as well, but
it is using the <SolidColorBrush> element. Note how the
color used by the brush is defined by its Color
attribute.
Example 1. Using a solid color brush, the XAML file (Page.xaml, project
SolidColorBrush)
Code View: <UserControl x:Class="SolidColorBrush.Page" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="500"> <Grid x:Name="LayoutRoot" Background="White"> <Canvas Width="500" Height="500" Background="White"> <Rectangle Canvas.Left="50" Canvas.Top="50" Width="200" Height="200" Canvas.ZIndex="5"> <Rectangle.Fill> <SolidColorBrush Color="Red" /> </Rectangle.Fill> </Rectangle> <Rectangle Canvas.Left="100" Canvas.Top="100" Width="200" Height="200" Canvas.ZIndex="4"> <Rectangle.Fill> <SolidColorBrush Color="Green" /> </Rectangle.Fill> </Rectangle> <Rectangle Canvas.Left="150" Canvas.Top="150" Width="200" Height="200" Canvas.ZIndex="3"> <Rectangle.Fill> <SolidColorBrush Color="Yellow" /> </Rectangle.Fill> </Rectangle> <Rectangle Canvas.Left="200" Canvas.Top="200" Width="200" Height="200" Canvas.ZIndex="2"> <Rectangle.Fill> <SolidColorBrush Color="Blue" /> </Rectangle.Fill> </Rectangle> <TextBlock Canvas.Left="250" Canvas.Top="250" FontSize="20" Text="Silverlight" Canvas.ZIndex="1"/> </Canvas> </Grid> </UserControl>
|
Brushes can do unique things. The most typical example is gradients.
A common form of a gradient is a radial gradient: the gradient starts at a
given origin (quite often the center of an object) and then goes radially
to the borders of the object. You can define an arbitrary number of stop
points: these are points where a certain color must be matched. So, all
you need to do is to define the stop points and associated colors;
Silverlight automatically calculates and draws all colors in between. The
XAML element for the brush is
<RadialGradientBrush>.
You must define a few parameters for this gradient:
Center
-
The center of the objects. You need to provide values between 0
and 1 for both the x and y
coordinates. Silverlight then calculates the actual coordinates
based on the dimension of the target object.
GradientOrigin
-
The center of the gradient. Again, provide values between 0 and 1 for both
coordinates.
RadiusX,
RadiusY
-
The x and y radii of the gradient, again as values between 0
and 1.
Stop colors are defined using the <GradientStop> element. You need to provide the color (Color attribute) and the
offset (Offset attribute, value between 0 and 1). Example 2 shows a radial gradient with three stop colors, and
Figure 1 has the output.
Example 2. Using a radial gradient, the XAML file (Page.xaml, project
RadialGradientBrush)
<UserControl x:Class="RadialGradientBrush.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="600">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>
<Ellipse Width="600" Height="600" Stroke="Black">
<Ellipse.Fill>
<RadialGradientBrush
Center="0.5 0.5" GradientOrigin="0.33 0.67"
RadiusX="0.5" RadiusY="0.5">
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="Green" Offset="0.33"/>
<GradientStop Color="Blue" Offset="0.67"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Canvas>
</Grid>
</UserControl>
The other form of gradient is a linear gradient: the color change
does not happen radially, but instead along a gradient axis. In the
associated XAML element, , you need to assign a start point and an end point, once again using values between 0 and 1, which are then mapped to
the actual coordinates. Example 3 shows
in action, and also includes a
line and markers that represent the radial axis and the stop points (trust
me with the values), as you can see in Figure 2.
Example 3. Using a linear gradient, the XAML file (Page.xaml, project
LinearGradientBrush)
Code View: <UserControl x:Class="LinearGradientBrush.Page" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="600" Height="600"> <Grid x:Name="LayoutRoot" Background="White"> <Canvas> <Rectangle Width="600" Height="600" Stroke="Black"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0.1 0.9" EndPoint="0.9 0.1"> <GradientStop Color="Red" Offset="0"/> <GradientStop Color="Green" Offset="0.33"/> <GradientStop Color="Blue" Offset="0.67"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Path Stroke="Black" Data="M 55 535 L 65 545 M 65 535 L 55 545" /> <Path Stroke="Black" Data="M 215 375 L 225 385 M 225 375 L 215 385" /> <Path Stroke="Black" Data="M 375 215 L 385 225 M 385 215 L 375 225" /> <Line X1="60" Y1="540" X2="540" Y2="60" Stroke="#7f000000" /> </Canvas> </Grid> </UserControl>
|
A final brush option is to use a special "filling" for a brush: an
image or a video file. So, when you have an image to fill an object,
Silverlight can automatically stretch the content so that it fits. You
could also play a video as a background for a rectangle or within an
ellipsis, just to give you a few ideas.
Using both brushes, ImageBrush and
VideoBrush, is quite similar. You have to provide the name of
the source file in an associated attribute, which is called
ImageSource for and
SourceName for . You can
instruct Silverlight on how to stretch the content so that it fits using
the Stretch attribute, assigning one of
these values:
None
-
The original content size remains.
Fill
-
The content fills up the whole available area, losing its aspect ratio.
Uniform
-
The content size is increased, maintaining the aspect ratio, until the content has either the width
or the height of the display area.
UniformToFill
-
The content size is increased, maintaining the aspect ratio, until the content width
and height are greater than or equal to the width and height of the
display area. If necessary, parts of the content are cropped.
Example 4 shows an image that is used to fill an
ellipsis. You can see in Figure 3 that this works as
expected and that you can display a rectangular image and video content as
well as use other shapes.
Example 4. Using an image brush, the XAML file (Page.xaml, project ImageBrush)
<UserControl x:Class="ImageBrush.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>
<Ellipse Canvas.Top="75" Width="300" Height="150" Stroke="Black">
<Ellipse.Fill>
<ImageBrush ImageSource="silverlight.png" />
</Ellipse.Fill>
</Ellipse>
</Canvas>
</Grid>
</UserControl>
NOTE
An alternative approach to defining the outline of an object is
to use the Clip property and provide a
Geometry object as its value, which will define the desired
shape.
There are many shapes in XAML, almost too many to keep track of,
but we covered the most important ones. And honestly, usually the UI comes
out of a design tool; as a programmer, you just have to add functionality,
and you'll learn how to do that in the next
chapter!