Template Bindings

Although the revised button template respects the content of the button, it ignores most other properties. For example, consider this instance that uses the template:

<Button Template="{StaticResource ButtonTemplate}" Content="A Templated Button" Margin="10" Padding="20"></Button>

This markup gives the button a Margin value of 10 and a Padding of 20. The element that holds the button is responsible for paying attention to the Margin property. However, the Padding property is ignored, leaving the contents of your button scrunched up against the sides. The problem here is the fact that the Padding property doesn't have any effect unless you specifically use it in your template. In other words, it's up to your template to retrieve the padding value and use it to insert some extra space around your content.

Fortunately, Silverlight has a feature that's designed exactly for this purpose: template bindings. By using a template binding, your control template can pull out a value from the control to which you're applying the template. In this example, you can use a template binding to retrieve the value of the Padding property and use it to create a margin around the ContentPresenter:

<ControlTemplate x:Key="ButtonTemplate" TargetType="Button"> <Border BorderBrush="Orange" BorderThickness="3" CornerRadius="10" Background="Red">

<ContentPresenter Margin="{TemplateBinding Padding}">

</ContentPresenter> </Border> </ControlTemplate>

This achieves the desired effect of adding some space between the border and the content. Figure 11-3 shows your modest new button.

Figure 11-3. A button with a customized control template

Note Template bindings are similar to ordinary data bindings (which you'll consider in Chapter 14), but they're lighter weight because they're specifically designed for use in a control template. They only support one-way data binding (in other words, they can pass information from the control to the template but not the other way around).

It turns out that there are quite a few details that you need to set in the ContentPresenter if you want to fully respect the properties of the Button class. For example, you need additional bindings if you want to get details like text alignment, text wrapping, and so on. In fact, buttons use a default control template that includes a ContentPresenter like this:

<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"

HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" TextAlignment="{TemplateBinding TextAlignment}" TextDecorations="{TemplateBinding TextDecorations}" TextWrapping="{TemplateBinding TextWrapping}"

VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"> </ContentPresenter>

The template binding for the Content property plays a key role—it extracts the content from the control and displays it in the ContentPresenter. However, this template binding is set implicitly. For that reason, you don't need to include it in your markup.

The only way you can anticipate what template bindings are needed is to check the default control template, as you'll see a bit later in this chapter (in the section "The Parts and States Model"). But in many cases, leaving out template bindings isn't a problem. In fact, you don't need to bind a property if you don't plan to use it or don't want it to change your template.

Note Template bindings support the Silverlight change-monitoring infrastructure that's built into all dependency properties. That means that if you modify a property in a control, the template takes it into account automatically. This detail is particularly useful when you're using animations that change a property value repeatedly in a short space of time.

0 0

Post a comment

  • Receive news updates via email from this site