CHAPTER 5 ELEMENTS
Tip Ordinarily, you’ll use a solid color brush
can create more exotic effects by filling in your text with gradients and tiled patterns using the fancy brushes
discussed in Chapter 9.
The TextBlock also provides a TextAlignment property (which allows you to center or right-justify
text), a Padding property (which sets the space between the text and the outer edges of the TextBlock),
and a few more properties for controlling fonts, inline formatting, text wrapping, and text trimming.
You’ll consider these properties in the following sections.
The TextBlock class defines font properties that determine how text appears in a control. These
properties are outlined in Table 5-2.
Table 5-2. Font-Related Properties of the Control Class
FontFamily The name of the font you want to use. Because Silverlight is a client-side technology, it’s
limited to just nine built-in fonts (Arial, Arial Black, Comic Sans MS, Courier New,
Georgia, Lucida, Times New Roman, Trebuchet MS, and Verdana). However, you can also
distribute custom fonts by going to a bit more work and packing them up with your
project assembly, as you’ll see shortly in the “Font Embedding” section.
The size of the font in pixels. Ordinary Windows applications measure fonts using points,
which are assumed to be 1/72 of an inch on a standard PC monitor, while pixels are
assumed to be 1/96 of an inch. Thus, if you want to turn a Silverlight font size into a more
familiar point size, you can use a handy trick—just multiply by 3/4. For example, a 20-
pixel FontSize is equivalent to a traditional 15-point font size.
The angling of the text, as represented as a FontStyle object. You get the FontStyle preset
you need from the static properties of the FontStyles class, which includes Normal and
Italic lettering. If you apply italic lettering to a font that doesn’t provide an italic variant,
Silverlight will simply slant the letters. However, this behavior gives only a crude
approximation of a true italic typeface.
FontWeight The heaviness of text, as represented as a FontWeight object. You get the FontWeight
preset you need from the static properties of the FontWeights class. Normal and Bold are
the most obvious of these, but some typefaces provide other variations such as Bold,
Light, ExtraBold, and so on. If you use Bold on a font that doesn’t provide a bold variant,
Silverlight will paint a thicker border around the letters, thereby simulating a bold font.
CHAPTER 5 ELEMENTS
FontStretch The amount that text is stretched or compressed, as represented by a FontStretch object.
You get the FontStretch preset you need from the static properties of the FontStretches
class. For example, UltraCondensed reduces fonts to 50 percent of their normal width,
while UltraExpanded expands them to 200 percent. Font stretching is an OpenType
feature that is not supported by many typefaces. The built-in Silverlight fonts don’t
support any of these variants, so this property is relevant only if you’re embedding a
custom font that does.
Obviously, the most important of these properties is FontFamily. A font family is a collection of
related typefaces—for example, Arial Regular, Arial Bold, Arial Italic, and Arial Bold Italic are all part of
the Arial font family. Although the typographic rules and characters for each variation are defined
separately, the operating system realizes they’re related. As a result, you can configure an element to use
Arial Regular, set the FontWeight property to Bold, and be confident that Silverlight will switch to the
Arial Bold typeface.
When choosing a font, you must supply the full family name, as shown here:
<TextBlock x:Name="txt" FontFamily="Times New Roman" FontSize="18">
It’s much the same in code:
txt.FontFamily = "Times New Roman";
txt.FontSize = "18";
When identifying a FontFamily, a shortened string is not enough. That means you can’t substitute
Times or Times New instead of the full name Times New Roman.
Optionally, you can use the full name of a typeface to get italic or bold, as shown here:
<TextBlock FontFamily="Times New Roman Bold">Some Text</TextBlock >
However, it’s clearer and more flexible to use just the family name and set other properties (such as
FontStyle and FontWeight) to get the variant you want. For example, the following markup sets the
FontFamily to Times New Roman and sets the FontWeight to FontWeights.Bold:
<TextBlock FontFamily="Times New Roman" FontWeight="Bold">Some Text</TextBlock >
Silverlight supports nine core fonts, which are guaranteed to render correctly on any browser and
operating system that supports Silverlight. They’re shown in Figure 5-1.
CHAPTER 5 ELEMENTS
Figure 5-1. Silverlight’s built-in fonts
In the case of Lucida, there are two variants with slightly different names. Lucida Sans Unicode is
included with Windows, while Lucida Grande is an almost identical font that’s included with Mac OS X.
To allow this system to work, the FontFamily property supports font fallback—in other words, you can
supply a comma-separated list of font names, and Silverlight will used the first supported font. The
default TextBlock font is equivalent to setting the FontFamily property to the string “Lucida Sans
Unicode, Lucida Grande.”
You might think that you can use more specialized fonts, which may or may not be present on the
client’s computer. However, Silverlight doesn’t allow this. If you specify a font that isn’t one of the nine
built-in fonts and it isn’t included with your application assembly (more on that in the next section),
your font setting will be ignored. This happens regardless of whether the client has an installed font with
the appropriate name. This makes sense—after all, using a font that’s supported on only some systems
could lead to an application that’s mangled or completely unreadable on others, which is an easy
mistake to make.
If you want to use nonstandard fonts in your application, you can embed them in your application
assembly. That way, your application never has a problem finding the font you want to use.
The embedding process is simple. First, you add the font file (typically, a file with the extension .ttf)
to your application and set Build Action to Resource. You can do this in Visual Studio by selecting the
font file in the Solution Explorer and changing its Build Action setting in the Properties page.
Next, when you set the FontFamily property, you need to use this format:
CHAPTER 5 ELEMENTS
For example, if you have a font file named BayernFont.ttf and it includes a font named Bayern, you
would use markup like this:
<TextBlock FontFamily="BayernFont.ttf#Bayern">This is an embedded font</TextBlock>
Figure 5-2 shows the result.
Figure 5-2. Using an embedded font
Alternatively, you can set the font using a stream that contains the font file. In this case, you need to
set the TextBlock.FontSource property with the font file stream and then set the TextBlock.FontFamily
property with the font name. For example, if you added the BayernFont.ttf file as a resource to a project
named FontTest, you can retrieve it programmatically using this code:
StreamResourceInfo sri = Application.GetResourceStream(
new Uri("FontTest;component/BayernFont.ttf", UriKind.Relative));
lbl.FontSource = new FontSource(sri.Stream);
lbl.FontFamily = new FontFamily("Bayern");
To pull the resource out of the current assembly, this code uses the
Application.GetResourceStream() method and a specialized URI syntax that always takes this form:
No matter which approach you use, the process of using a custom font is fairly easy. However, font
embedding raises obvious licensing concerns. Most font vendors allow their fonts to be embedded in
documents (such as PDF files) but not applications (such as Silverlight assemblies). The problem is
obvious—users can download the XAP file by hand, unzip it, retrieve the font resource, and then access
it on their local computers. Silverlight doesn’t make any attempt to enforce font licensing, but you
should make sure you’re on solid legal ground before you redistribute a font.
You can check a font’s embedding permissions using Microsoft’s free font properties extension
utility, which is available at www.microsoft.com/typography/TrueTypeProperty21.mspx. Once you install
this utility, right-click any font file, and choose Properties to see more detailed information about it. In
particular, check the Embedding tab for information about the allowed embedding for this font. Fonts
marked with Installed Embedding Allowed are suitable for Silverlight applications, while fonts with
Editable Embedding Allowed may not be. Consult with the font vendor for licensing information about a
CHAPTER 5 ELEMENTS
Note If all else fails, you can get around licensing issues by changing your fonts to graphics. This works for
small pieces of graphical text (for example, headings) but isn’t appropriate for large blocks of text. You can save
graphical text as a bitmap in your favorite drawing program, or you can convert text to a series of shapes using
Silverlight’s Path element (which is discussed in Chapter 8). You can convert graphical text to a path using
Expression Designer or Expression Blend (simply select the TextBlock and choose Object
to see an example in which a Silverlight application calls a web service that
dynamically generates a path for non-Western text. The web service returns the path data to the Silverlight
application, which displays it seamlessly.
You can add underlining to any font by setting the TextDecorations property to Underline:
<TextBlock TextDecorations="Underline">Underlined text</TextBlock>
In WPF, there are several types of text decorations, including overlines and strikethrough. However,
currently, Silverlight includes only underlining.
If you want to underline an individual word in a block of text, you’ll need to use inline elements, as
described in the next section.
In many situations, you’ll want to format individual bits of text but keep them together in a single
paragraph in a TextBlock. To accomplish this, you need to use a Run object inside the TextBlock
element. Here’s an example that formats several words differently (see Figure 5-3):
<TextBlock FontFamily="Georgia" FontSize="20" >
This <Run FontStyle="Italic" Foreground="YellowGreen">is</Run> a
<Run FontFamily="Comic Sans MS" Foreground="Red" FontSize="40">test.</Run>
CHAPTER 5 ELEMENTS
Figure 5-3. Formatting text with runs
A run supports the same key formatting properties as the TextBlock, including Foreground,
TextDecorations, and the five font properties (FontFamily, FontSize, FontStyle, FontWeight, and
Technically, a Run object is not a true element. Instead, it’s an inline. Silverlight provides two just
types of inlines—the LineBreak class that you saw earlier and the Run class. You can interact with the
runs in your TextBlock through the TextBlock.Inlines collection. In fact, the TextBlock actually has two
overlapping content models. You can set text through the simple Text property, or you can supply it
through the Inlines collection. However, the changes you make in one affect the other, so if you set the
Text property, you’ll wipe out the current collection of inlines.
Note The inline Run and LineBreak classes are part of the text element model, which is supported (in a more
fully featured way) by the RichTextBox control discussed later in this chapter.
To wrap text over several lines, you use the TextWrapping property. Ordinarily, TextWrapping is set to
TextWrapping.NoWrap, and content is truncated if it extends past the right edge of the containing
element. If you use TextWrapping.Wrap, your content will be wrapped over multiple lines when the
width of the TextBlock element is constrained in some way. (For example, you place it into a
proportionately sized or fixed-width Grid cell.) When wrapping, the TextBlock splits lines at the nearest
space. If you have a word that is longer than the available line width, the TextBlock will split that word
wherever it can to make it fit.
When wrapping text, the LineHeight and LineStackingStrategy properties become important. The
LineHeight property can set a fixed height (in pixels) that will be used for every line. However, the
CHAPTER 5 ELEMENTS
LineHeight can be used to increase the line height only—if you specify a height that’s smaller than
what’s required to show the text, your setting will be ignored.
The LineStackingStrategy determines what the TextBlock will do when dealing with multiline
content that uses different fonts. You can choose to use the standard behavior, MaxHeight, which makes
each line as high as it needs to be to fit the tallest piece of text it contains, or you can use
BlockLineHeight, which sets the lines to one fixed height—the height set by the LineHeight property.
Shorter text will then have extra space, and taller text will overlap with other lines. Figure 5-4 compares
the different options.
Figure 5-4. Two different ways to calculate line height
The TextBlock wraps text in a neat, rectangular region. It’s not possible to wrap text around curves
or the contours of nearby shapes. However, you can simulate such effects using the RichTextBox’s
overflow feature, as described later in this chapter.
As you learned in the previous section, text that doesn’t fit the width of its container has two options:
wrap or be truncated. For example, if you have a sentence like “Silverlight is a fantastic platform,” it
might be truncated like this:
Silverlight is a fant
CHAPTER 5 ELEMENTS
The TextTrimming property gives you a slightly more graceful way to deal with this situation. If you
set the TextTrimming property to WordEllipsis (the only option other than the default), Silverlight adds
an ellipsis at the end of truncated text. So, the previous example might come out like this:
Silverlight is a ...
This gives the user a visual cue that the full text isn’t shown.
If your type looks a little congested, you can use the LineHeight property to add vertical space between
the lines (as you’ve already seen), and you can use the CharacterSpacing property to add space
horizontal space between letters on the same line. Here’s an example:
<TextBlock FontSize="20" CharacterSpacing="100">
These letters are spaced out.
The CharacterSpacing property takes a value that’s measured in 1/1000
of the current font size. So
if you set CharacterSpacing to a generous 100 and your font size is 20 pixels, you’ll get 2 pixels of extra
space between each letter (because 100/1000
20 = 2).
The default value for CharacterSpacing is 0, which gets you no extra space. If you want to draw the
letters of a line closer together (and possibly even overlap), you can simply set CharacterSpacing to a
Displaying an image is one of the easier tasks in Silverlight. You simply need to add an Image element
and set its Source property. However, there are some limitations that you need to understand.
The most obvious limitation is that the Image element supports just two image formats. It has full
support for JPEG and fairly broad support for PNG (although it doesn’t support PNG files that use 64-bit
color or grayscale). The Image element does not support GIF files. There are two reasons for this
omission—it allows the Silverlight download to remain that much slimmer, and it avoids potential
confusion between the Silverlight animation model and the much more basic (and unsupported)
animated GIF feature that’s used on the Web.
It’s also important to recognize that the Image.Source property is set with a relative or absolute URI.
Usually, you’ll use a relative URI to display an image that you’ve added to your project as a resource. For
example, if you add a new image named grandpiano.jpg to your project, Visual Studio will automatically
configure it to be a resource, and it will embed that resource in the compiled assembly as a block of
binary data. At runtime, you can retrieve that image using its resource name (which is the file name it
has in the Solution Explorer). Here’s how:
Or, assuming the image is in a project subfolder named Images, you can retrieve it like so:
Alternatively, you can construct the URI in code and set the Image.Source property
img.Source = new BitmapImage(new Uri("grandpiano.jpg", UriKind.Relative));
CHAPTER 5 ELEMENTS
You can also use image URIs to point to images that aren’t embedded in your application. You can
show images that are located on the same website as your Silverlight application, or images that exist on
However, there’s one catch. When testing a file-based website (one that doesn’t use an ASP.NET
website and the Visual Studio test web server), you won’t be able to use absolute URLs. This limitation is
a security restriction that results from the mismatch between the way you’re running your application
(from the file system) and the way you want to retrieve your images (from the Web, over HTTP). The
same limitation comes into play if you attempt to access an image over HTTPS when your Silverlight
page was accessed through HTTP (or vice versa).
For more information and to see a few examples that demonstrate your different options for using
URIs and managing resources, refer to Chapter 6.
Tip Interestingly, Silverlight uses bitmap caching to reduce the number of URI requests it makes. That means
you can link to an image file on a website multiple times, but your application will download it only once.
Images can be resized in two ways. First, you can set an explicit size for your image using the Height and
Width properties. Second, you can place your Image element in a container that uses resizing, such as a
proportionately sized cell in a Grid. If neither of these factors comes into play—in other words, you don’t
set the Height and Width properties and you place your Image in a simple layout container like the
Canvas—your image will be displayed using the native size that’s defined in the image file.
To control this behavior, you can use the Stretch property. The Stretch property determines how an
image is resized when the dimensions of the Image element don’t match the native dimensions of the
image file. Table 5-3 lists the values you can use for the Stretch property, and Figure 5-5 compares them.
Table 5-3. Values for the Stretch Enumeration
Your image is stretched in width and height to fit the Image element dimensions
The image keeps its native size.
The image is given the largest possible size that fits in the Image element and doesn’t
change its aspect ratio. This is the default value.
UniformToFill The width and height of the image are sized proportionately until the image fills all the
available height and width. For example, if you place a picture with this stretch setting
into an Image element that’s 100
200 pixels, you’ll get a 200
200 picture, and part of it
will be clipped off.
CHAPTER 5 ELEMENTS
Figure 5-5. Four different ways to size an image
Several factors can cause an image not to appear, such as using a URI to a nonexistent file or trying to
display an image in an unsupported format. In these situations, the Image element raises the
ImageFailed event. You can react to this event to determine the problem and take alternative actions.
For example, if a large image is not available from the Web, you can substitute a small placeholder that’s
embedded in your application assembly.
Image errors are not fatal, and your application will continue running even if it can’t display an
image. In this situation, the Image element will remain blank. Your image will also be blank if the image
data takes a significant amount of time to download. Silverlight will perform the image request
asynchronously and render the rest of the layout in your page while waiting.
Content controls are a specialized type of controls that are designed to hold (and display) a piece of
content. Technically, a content control is a control that can contain a single nested element. The one-
child limit is what differentiates content controls from layout containers, which can hold as many nested
elements as you want.
As you learned in Chapter 3, all Silverlight layout containers derive from the Panel class, which gives
the support for holding multiple elements. Similarly, all content controls derive from the
ContentControl class. Figure 5-6 shows the class hierarchy.
Documents you may be interested
Documents you may be interested