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?

Common Layout Properties

Common Layout Properties

All user-interface elements have a standard set of layout properties, inherited from the FrameworkElement base class. We have seen a few of these in passing in the preceding section, but we will now look at them all in a little more detail.

2.8.1. Width and Height

You can set these properties to specify an exact width and height for your element. You should try to avoid using thesein general it is preferable to let elements determine their own size where possible. Allowing elements to size to content makes changing your user interface less effort. It can also simplify localization. However, you will occasionally need to provide a specific size.

If you specify a Width or Height, the layout system will always attempt to honor your choices. Of course if you make an element wider than the screen, WPF can't make the screen any wider, but as long as what you request is possible, it will be done.

2.8.2. MinWidth, MaxWidth, MinHeight, and MaxHeight

These properties allow you to specify upper and lower limits on the size of an element. If you need to constrain your user interface's layout, it is usually better to use these than Width and Height where possible. By specifying upper and lower limits, you can still allow WPF some latitude to automate the layout.

It is possible to mandate limits that simply cannot be fulfilled. For example, if you request a MinWidth of 10000, WPF won't be able to honor that request unless you have some very exotic display hardware. In these cases, your element will be truncated to fit the space available.

2.8.3. HorizontalAlignment and VerticalAlignment

These properties control how an element is placed inside a parent when there is more room available than necessary. For example, a vertical StackPanel will be as wide as the widest element, meaning that any narrower elements are given excess space. A DockPanel will provide enough space for an element to fill an edge or all the remaining space. Alignment is for these sorts of scenarios, enabling you to determine what the child element does with the extra space.

The default setting for both of these properties is Stretch: when excess space is available, the element will be enlarged to fill that space. The alternatives are Left, Center, and Right for HorizontalAlignment, and Top, Center, and Bottom for VerticalAlignment. If you choose any of these, the element will not be stretchedit will use its natural height or width and will then be positioned to one side or in the center.

2.8.4. Margin

This property determines the amount of space that should be left around the element during layout.

Margin can be specified as a single number, a pair of numbers, or a list of four numbers. When one number is used, this indicates that the same amount of space should be left on all sides. With two numbers, the first indicates the space to the left and right while the second indicates the space above and below. When four numbers are specified, they indicate the amount of space on the left, top, right, and bottom sides, respectively.

2.8.5. Padding

Padding is similar to Margin, except it is internal rather than external. While Margin indicates how much space should be left around the outside of an element, Padding specifies how much space should be left between a control's outside, and its internal content.

Padding is not present on all WPF elements, since not all elements have internal content. It is defined by the Control base class.

Example 2-30 shows three buttons, one with just margin, one with both margin and padding, and one with just padding. It also fills the area behind the buttons with color so the effects of the margin can be seen.

Example 2-30. Margin versus padding
<Grid ShowGridLines="True">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>

        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Rectangle Grid.ColumnSpan="2" Fill="Cyan" />

    <Button Grid.Column="0" Margin="20">Click me!</Button>
    <Button Grid.Column="1" Margin="10" Padding="10">Click me!</Button>

    <Button Grid.Column="2" Padding="20">Click me!</Button>

</Grid>

Figure 2-37 shows the results. The button with margin but no padding has appeared at its normal size, but has space around it. The middle button is larger, because the padding causes space to be added around its content. The third button is larger still because it has more padding, but it has no space around it since it has no margin.

Figure 2-37. Buttons with margin and padding


2.8.6. FlowDirection

The FlowDirection property controls how text flows. The default is left to right, then top to bottom. Many cultures use the alternative right-to-left then top-to-bottom flow style.

2.8.7. RenderTransform and LayoutTransform

The RenderTransform and LayoutTransform properties can both be used to apply a transform, such as scaling or rotation, to an element and all of its children. The use of transforms is described in Chapter 7, but it is useful to understand their impact on layout.

If you apply a transform that doubles the size of an element, the element will appear to be twice as large onscreen. You would normally want the layout system to take this into accountif a Rectangle with a Width of 100 is scaled up to twice its size, it will normally make sense for the layout system to treat it as having an effective width of 200. However, you might sometimes want the transformation to be ignored for layout purposes. For example, if you are using a transform in a short animation designed to draw attention to a particular part of the UI, you probably don't want the entire UI's layout to be changed as a result of that animation.

You can apply a transform to an object using either LayoutTransform or RenderTransform. The former causes the transform to be taken into account by the layout system, while the latter causes it to be ignored. Example 2-31 shows three buttons, one containing untransformed content and the other two containing content transformed with these two properties.

Example 2-31. RenderTransform and LayoutTransform
<Button><TextBlock>Foo bar</TextBlock></Button>

<Button><TextBlock RenderTransform="scale 3">Foo bar</TextBlock></Button>
<Button><TextBlock LayoutTransform="scale 3">Foo bar</TextBlock></Button>

The results are shown in Figure 2-38. As you can see, the button with content scaled by RenderTransform is the same size as the unscaled one. The presence of the transform has had no effect on layout, and the content no longer fits inside the space allocated for it. However, the LayoutTransform has been taken into account by the layout systemthe third button has been enlarged in order for the scaled content to fit.

Figure 2-38. RenderTransform and LayoutTransform


The way in which LayoutTransform is dealt with by the layout system is straightforward for simple scaling transforms. The size allocated for the content is scaled up accordingly. But what about rotations? Figure 2-39 shows a button whose content has a LayoutTransform of "rotate 30". This is not a scaling transform, but notice that the button has grown to accommodate the content: it is taller than a normal button.

Figure 2-39. LayoutTransform and rotation


When it encounters a LayoutTransform, the layout system simply applies that transform to the bounding box, and makes sure that it provides enough space to hold the transformed bounding box. This can occasionally lead to surprising results. Consider the two buttons in Example 2-32.

Example 2-32. Rotation of content
<Button>
    <Line Stroke="Blue" Y1="30" X2="100" />

</Button>
<Button>
    <Line LayoutTransform="rotate 50" Stroke="Blue" Y1="30" X2="100" />
</Button>

These are shown in Figure 2-40. The top button looks as you would expect: the button is large enough to contain the graphical content. But the bottom one is rather surprisingthe button appears to be much larger than necessary.

Figure 2-40. Rotated content


This result only makes sense when you consider the bounding boxremember that the layout system decides how much space to allocate by applying the LayoutTransform to the bounding box. So let's look at it again, this time with the bounding boxes shown. Example 2-33 is a modified version of Example 2-32, with Border elements added to show the bounding box of the lines.

Example 2-33. Rotation showing bounding box
<Button>
    <Border BorderBrush="Black" BorderThickness="1">
        <Line Stroke="Blue" Y1="30" X2="100" />
    </Border>
</Button>
<Button>

    <Border BorderBrush="Black" BorderThickness="1"
            LayoutTransform="rotate 50" >
        <Line Stroke="Blue" Y1="30" X2="100" />
    </Border>
</Button>

In Figure 2-41, we can now see the bounding box of the content. The button on the bottom shows this bounding box with the same 30 degree rotation as has been applied to the line. This makes it clear that the button is exactly large enough to hold this rotated bounding box.

Figure 2-41. Rotated content with bounding boxes


You might be wondering why WPF doesn't simply calculate a new bounding box for the transformed content instead of transforming the existing one. The reason is that calculating a new bounding box may not be possible. Some elements, such as Canvas, can declare a width and height that does not directly reflect their apparent size. The only sensible way in which the layout system can deal with such elements is to treat their logical shape as being rectangular. Using this approach of transforming the bounding box everywhere ensures consistent behavior.


©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