Windows Presentation Foundation

Hello, WPF

WPF from Scratch
Navigation Applications
Content Model
Layout
Controls
Data Binding
Dependency Properties
Resources
Styles and Control Templates
Graphics
Application Deployment
Where Are We?

Layout

Introduction
Layout Basics
DockPanel
StackPanel
Grid
Canvas
Viewbox
Text Layout
Common Layout Properties
When Content Doesn't Fit
Custom Layout
Where Are We?

Controls

Introduction
What Are Controls?
Handling Input
Built-In Controls
Where Are We?

Data Binding

Introduction
Without Data Binding
Data Binding
Binding to List Data
Data Sources
Master-Detail Binding
Where Are We?

Styles and Control Templates

Introduction
Without Styles
Inline Styles
Named Styles
Element-Typed Styles
Data Templates and Styles
Triggers
Control Templates
Where Are We?

Resources

Introduction
Creating and Using Resources
Resources and Styles
Binary Resources
Global Applications
Where Are We?

Graphics

Introduction
Graphics Fundamentals
Shapes
Brushes and Pens
Transformations
Visual-Layer Programming
Video and 3-D
Where Are We?

Animation

Animation Fundamentals
Timelines
Storyboards
Key Frame Animations
Creating Animations Procedurally
Where Are We?

Custom Controls

Introduction
Custom Control Basics
Choosing a Base Class
Custom Functionality
Templates
Default Visuals
Where Are We?

ClickOnce Deployment

A Brief History of Windows Deployment
ClickOnce: Local Install
The Pieces of ClickOnce
Publish Properties
Deploying Updates
ClickOnce: Express Applications
Choosing Local Install versus Express
Signing ClickOnce Applications
Programming for ClickOnce
Security Considerations
Where Are We?

Text Layout

Text Layout

The simplest element for presenting text is TextBlock, which is efficient but has limited functionality. TextFlow offers more advanced typography and layout functionality but with slightly more overhead.

2.7.1. TextBlock

TextBlock is useful for putting short blocks of text into a user interface. If you don't require any special formatting of the text, you can simply wrap your text in a TextBlock:

<TextBlock>Hello, world!</TextBlock>

However, even though TextBlock is the simplest text-handling element, it is capable of a little more than this example shows. For example, it has a set of properties for controlling the font, shown in Table 2-2.

Table 2-2. TextBlock font properties

Property

Usage

FontFamily

Typeface name; e.g., "Times New Roman" or "Lucida Console"

FontSize

Size of the font

FontStretch

Used to indicate condensed or expanded versions of a typeface, where available

FontStyle

Normal, Oblique, or Italic

FontWeight

Weight; e.g., "Bold," "Light" or "Black"


2.7.1.1. Text wrapping

The TextBlock is capable of wrapping text across multiple lines where necessary. This is enabled with the TextWrap property, as shown in Example 2-20.

Example 2-20. Text wrapping
<TextBlock FontSize="24" TextWrap="Wrap">
    Split across multiple lines
</TextBlock>

The result is shown in Figure 2-28. (If you try this, note that you will only see wrapping if the TextBlock is in a sufficiently narrow space to need it. Even with wrapping enabled, the TextBlock prefers to put everything on one line when it can.)

Figure 2-28. Text wrapping


This wrapping facility can also be used to flow other elements across multiple lines. The TextBlock can have a mixture of text and arbitrary elements, as you can see in Example 2-21.

Example 2-21. Flowing non-text elements
<TextBlock TextWrap="Wrap">

    <Button>Split</Button>
    <CheckBox>across</CheckBox>
    <TextBox>multiple</TextBox>
    lines

</TextBlock>

The results are shown in Figure 2-29. Elements are treated in exactly the same way as wordsif they are too wide to fit on the current line, they will be moved onto the next line.

Figure 2-29. Element wrapping


2.7.1.2. Text styles

As well as supporting a mixture of text and other elements, the TextBlock is also able to support a mixture of text styles . If you would like a word to be in italic, bold, or a different typeface, this is easily achieved. WPF defines a number of so-called "inline" elements for modifying the appearance of text within a single control. These are shown in Table 2-3.

Table 2-3. Inline text elements

Element name

Usage

AccessKey

Underlines the section in the style of an accelerator key.

Bold

Makes the text bold.

Hyperlink

Displays the text as a hyperlink.

Italic

Makes the text italic.

Subscript

Shows the text raised, and in a smaller typeface.

Superscript

Shows the text lowered, and in a smaller typeface.

Underline

Underlines the text.


Example 2-22 shows a few of these inline elements in use.

Example 2-22. Inline elements
<TextBlock FontSize="18">
    <AccessKey>T</AccessKey>his <Italic>is</Italic> <Bold>rather</Bold>

    <Underline>messy</Underline>. <Hyperlink>www.example.com</Hyperlink>
</TextBlock>

2.7.2. Text and Whitespace

As Figure 2-30 shows, there's a trap for the unwary when using inline elements. XML parsing does not necessarily preserve whitespace, because many XML documents use whitespace for formatting. For example, most of the XAML in this book uses indentation to make the structure of the markup easier to follow. When there is nothing but whitespace between two elements, the XAML compiler strips out this space by default. Unfortunately, this is undesirable in this particular exampleit has removed the space we wanted between the words. (Notice that it has only affected adjacent inline elements. We can still see a space between "This" and "is," and between the "." and "www.example.com" because in those cases, there was more than just whitespace between the inline elements.)

Figure 2-30. Inline elements with lost spaces


The solution to this is a standard XML feature. You can mark elements with the xml:space="preserve" attribute to indicate that the whitespace it contains is significant. Example 2-23 shows a modified version that fixes the problem.

Example 2-23. preserve attribute
<TextBlock FontSize="18" xml:space="preserve"><AccessKey>T</AccessKey>his
<Italic>is</Italic> <Bold>rather</Bold> <Underline>messy</Underline>.

<Hyperlink>www.example.com</Hyperlink></TextBlock>

Note that the code in Example 2-23 has been split across multiple lines in order to fit into the book. If you try this, type it in on a single line.

This solves the problem, as Figure 2-31 shows. However, it has come at the cost of making the markup much more untidy. We cannot add any spaces, tabs, or line breaks in order to make the markup easier to read, as these will now be faithfully represented onscreen.


Figure 2-31. Inline elements with preserved space


As a compromise, you could use the xml:space attribute more selectively. Rather than applying it to the top level, you could apply it to just those elements that are causing you problems. This might make the markup a little more verbose, but it does give you more freedom to format it however you like. Example 2-24 uses this technique, and produces the same output as Example 2-23.

Example 2-24. space attribute
<TextBlock FontSize="18">
    <AccessKey>T</AccessKey>his <Italic>is</Italic>
    <Bold xml:space="preserve"> rather </Bold>

    <Underline>messy</Underline>. <Hyperlink>www.example.com</Hyperlink>
</TextBlock>

If you place a line break in a section of text marked with xml:space="preserve", that line break will be honored on the display. If you would like to add a line break without using xml:space="preserve", you can add a LineBreak element.

2.7.2.1. Text alignment

The TextBlock offers a TextAlignment property that allows you to choose whether text is left-aligned, right-aligned, centered, or justified. Example 2-25 shows all of these styles. Figure 2-32 shows the results.

Figure 2-32. Text alignment


Example 2-25. Text alignment
<StackPanel Orientation="Horizontal">
  <TextBlock Width="80" TextAlignment="Left" TextWrap="Wrap" Margin="15">
    This text is left-aligned. Its right edge is ragged.
  </TextBlock>

  <TextBlock Width="80" TextAlignment="Right" TextWrap="Wrap" Margin="15">
    This text is right-aligned. Its left edge is ragged.
  </TextBlock>
  <TextBlock Width="110" TextAlignment="Center" TextWrap="Wrap" Margin="15">
    This text is centered. Both edges are ragged, in a symmetrical way.
  </TextBlock>
  <TextBlock Width="120" TextAlignment="Justify" TextWrap="Wrap" Margin="15">

    This text is justified. Both edges  are straight. Words are spaced out
    in order to achieve this
  </TextBlock>
</StackPanel>

The ability of the TextBlock to support wrapping, arbitrary inline UI elements, line breaking, and a mixture of text styles makes it useful for a wide variety of simple text scenarios. However, its layout capabilities are somewhat limited compared to the TextFlow element.

2.7.3. TextFlow

TextFlow can perform all of the same duties as TextBlock, but provides much more sophisticated layout support. As well as supporting all of the inline elements described in the previous section, TextFlow adds support for so-called "block" elements. These are listed in Table 2-4.

Table 2-4. Block element types

Element name

Usage

Paragraph

A paragraph

List

Numbered or bulleted list

Table

A table of information

Floater

An element arranged outside of the main flow, and which everything else can flow around

Figure

Similar to a Floater, but with a caption, and with extra control over exactly where the element is placed


2.7.3.1. Paragraph

The Paragraph element doesn't strictly enable anything that couldn't be achieved with the LineBreak element in a TextBlock. However, it is often more convenient, as paragraphs are part of the logical structure of the text. It usually makes more sense to deal with paragraphs rather than the gaps between them.

For example, if a particular paragraph represents a heading, you can apply a font or style to the Paragraph element containing the heading. (Paragraph supports all of the same font properties as TextBlock.) Choosing a font for a LineBreak, on the other hand, would not be useful.

2.7.3.2. List

The List element allows numbered or bullet lists to be added to the text. The same syntax is used whether you require numbers or bullets. The style is selected with the MarkerStyle property, as shown in Example 2-26.

Example 2-26. List marker styles
<TextFlow FontSize="18">
    <List MarkerStyle="Decimal">
        <ListItem><Paragraph>First item</Paragraph></ListItem>

        <ListItem><Paragraph>Second item</Paragraph></ListItem>
    </List>
</TextFlow>

The MarkerStyle property supports several styles, both numeric and bulleted. Figure 2-33 shows all of them in use.

Figure 2-33. List styles


2.7.3.3. Table

The Table element presents information in tabular form. It may seem curious for WPF to offer both a Table and a Grid element, but they address slightly different problems. Although there is some overlap in functionality, neither offers a complete subset of the other's functionality. The Grid is designed entirely for laying out elements and can be used to arrange user interfaces that don't look obviously tabular (e.g., it is useful for a wide range of dialog layouts). The Table is designed exclusively for presenting tables of information.

Table is less flexible than Grid when it comes to layout. Each cell in a Table must be occupied by exactly one item. (Items can still span cells.) However, it does provide some features not offered by Grid. It has support for header and footer information. And if a table is viewed in a context that supports pagination, such as printing or the DocumentViewer control, Table has special support for being split across multiple pages.

Example 2-27 shows a Table with headers. The result is shown in Figure 2-34.

Example 2-27. Table
<Table CellSpacing="6">
    <TableHeader>

        <TableRow FontSize="24" FontWeight="Bold">
            <TableCell ColumnSpan="3" TextAlignment="Center" >
                Ice Cream
            </TableCell>
        </TableRow>
        <TableRow FontWeight="Bold" FontSize="18" Background="LightGray">
            <TableCell>Type</TableCell>

            <TableCell>Description</TableCell>
            <TableCell>Availability</TableCell>
        </TableRow>
    </TableHeader>
    <TableBody>

        <TableRow>
            <TableCell>Chocolate</TableCell>
            <TableCell>Yummy</TableCell>
            <TableCell>Widespread</TableCell>

        </TableRow>
        <TableRow>
            <TableCell>Cookie Dough</TableCell>
            <TableCell>Extra yummy</TableCell>
            <TableCell>Scarce - Ian ate it all</TableCell>

        </TableRow>
        <TableRow>
            <TableCell>Artichoke</TableCell>
            <TableCell>Gruesome</TableCell>
            <TableCell>Rarely available</TableCell>

        </TableRow>
    </TableBody>
</Table>

Figure 2-34. Table


2.7.3.4. Floater

A Floater is a block that is not laid out as part of the overall flow of the text. It is usually arranged to one side, and the rest of the content of the TextFlow flows around it.

Example 2-28 shows a typical use of a Floater. This TextFlow contains some Paragraphs of text. It has one Floater acting as a sidebar. Figure 2-35 shows the results.

Figure 2-35. TextFlow with Floater


Example 2-28. TextFlow with Floater
<TextFlow>
    <Paragraph FontWeight="Bold">Metasyntactic Variables</Paragraph>

    <Paragraph>

        <Floater Background="LightBlue" Margin="10" Width="230">
            <Paragraph FontWeight="Bold">Foo and Bar</Paragraph>
            <Paragraph>
                Many developers are unaware of the origin of
                the most popular placeholders,'Foo' and 'Bar'.
            </Paragraph>

            <Paragraph>
                They originate from the Air Force. They are a
                corruption of FUBAR, the polite expansion of
                which is 'Fouled Up Beyond All Recognition.'
            </Paragraph>
        </Floater>
    </Paragraph>
    <Paragraph>

        In describing software, we must often describe
        constructs or processes in the most general of
        terms. Using concrete examples is not always wise,
        because specific details of the example can get
        in the way.
    </Paragraph>

    <Paragraph>
        English offers only a limited number of nouns
        suitable for discussing abstract constructs.
        You can only use the word 'thing' so many times
        without sounding stupid, so most software
        practitioners use words such as 'Foo' and 'Bar'
        to augment the number of abstract nouns available.
        These words are sometimes referred to as
        'metasyntactic variables'
    </Paragraph>
</TextFlow>

By default, a Floater will appear to the right of the main text. However, you can change this with the HorizontalAlignment property, which supports three options: Left, Center, and Right. Example 2-29 shows all three in use, and Figure 2-36 shows the results.

Example 2-29. Floater alignment
<TextFlow>

    <Paragraph>
        <Floater Background="Yellow" Margin="10,0" HorizontalAlignment="Left">
            <Paragraph FontWeight="Bold">Left Floater</Paragraph>

        </Floater>
    </Paragraph>
    <Paragraph>
        This is some normal text.
    </Paragraph>
    <Paragraph>
        <Floater Background="Yellow" Margin="10,5" HorizontalAlignment="Center">

            <Paragraph FontWeight="Bold">Center Floater</Paragraph>
        </Floater>
    </Paragraph>
    <Paragraph>
        This is some more normal text. Notice how it flows both
        sides of the centered floater.
    </Paragraph>

    <Paragraph>
        <Floater Background="Yellow" Margin="10,0" HorizontalAlignment="Right">
            <Paragraph FontWeight="Bold">Right Floater</Paragraph>
        </Floater>
    </Paragraph>

    <Paragraph>
        This is yet more normal text.
    </Paragraph>

</TextFlow>

Figure 2-36. Floater alignment


2.7.3.5. Figure

Figure provides a similar service to Floater; it allows a block to be put outside of the main text, which the main text will flow around. However, you can give the TextFlow more freedom to decide where to position a Figure than a Floater.

Figure has a HorizontalAnchor property that indicates where the figure should appear. This does a very similar job to the floater's HorizontalAlignment, and offers the same three options: left, middle and center. However, unlike the floater, you can specify how far the figure can be moved vertically in order to fit it into the text. By allowing WPF some flexibility for vertical placement, it may be able to do a better job of arranging the document onto the available screen space than would otherwise be possible.

For example, you can specify PageLeft, PageCenter, or PageRight. These indicate that the figure should be placed to the left of, in the center of, or to the right of the page, respectively. This tells the TextFlow that any vertical position is allowed so long as it the figure is displayed on the same page as the paragraph after the figure. ContentLeft, ContentCenter, and ContentRight allow the figure to appear at any vertical location. (Pagination is only relevant when printing, or using a paginating control such as the DocumentViewer. When viewing text without pagination, Page and Content positioning are equivalent.)

You can choose to be more restrictive by specifying ParagraphLeft, ParagraphCenter, or ParagraphRight anchor values. These require the figure to be displayed next to the paragraph that follows the figure. These horizontal anchor values are equivalent to the three HorizontalAlignment options we saw with Floater.

There is also a VerticalAnchor property. This lets you specify the vertical positioning you require, allowing WPF some latitude with the vertical location. The available options are essentially the same as for the horizontal anchor, but with Left, Center, and Right replaced with Top, Center, and Bottom.

Armed with the TextFlow, we are now in a position to complete the layout of our document viewer. The TextFlow offers all of the layout features we require to provide richly formatted text. All we need to do is wrap it in a ScrollViewer to enable scrolling through long documents.


©2008 FAQ - WPF Labs - Discuss - Terms of Use - Privacy Policy - About WPF
- Interview Questions - Sharepoint Articles - Interview Questions Resource Library - All about LINQ - MS Knowledgebase Articles - Electronics and Hardware discussions