Control templates, Visual State Manager, and Event Handlers in Silverlight 4

0
142
7 min read

Skinning a control

So far, you’ve seen that while styles can change the look of a control, they can only go so far. No matter how many changes we make, the buttons still look like old-fashioned buttons. Surely, there must be a way to customize a control further to match our creative vision. There is a way, its called skinning.

Controls in Silverlight are extremely flexible and customizable. This flexibility stems from the fact that controls have both a VisualTree and a LogicalTree. The VisualTree deals with all the visual elements in a control, while the Logical tree deals with all the logical elements. All controls in Silverlight come with a default template, which defines what a control should look like. You can easily override this default template by redefining a control’s visual tree with a custom one.

Designers can either work directly with XAML in Blend or use a design tool that supports exporting to XAML. Expression Design is one such tool. You can alsoimport artwork from Adobe Illustrator and Adobe Photoshop from within Blend.

In our scenario, let us pretend that there is a team of graphic designers. From time to time graphic designers will provide us with visual elements and, if we’re lucky, snippets of XAML. In this case, the designers have sent us the XAML for a rectangle and gradient for us to base our control on:

<Rectangle Stroke="#7F646464" Height="43" Width="150"
StrokeThickness="2" RadiusX="15" RadiusY="15" VerticalAlignment="Top">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFEE9D9D" Offset="0.197"/>
<GradientStop Color="#FFFF7D7D" Offset="0.847"/>
<GradientStop Color="#FFF2DADA" Offset="0.066"/>
<GradientStop Color="#FF7E4F4F" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>

After inputting the above XAML, you will be presented with this image:

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

We need to make this rectangle the template for our buttons.

Time for action – Skinning a control

We’re going to take the XAML snippet above and skin our buttons with it. In order to achieve this we will need to do the following:

  1. Open up the CakeNavigationButtons project in Blend.
  2. In the MainPage.XAML file, switch to XAML View, either by clicking the XAML button on the upper-right corner of the art board or choosing View|Active Document View|XAML from the menu bar.
  3. Type in the following XAML after the closing tag for the StackPanel:
  4. (</StackPanel>)
    <Rectangle Stroke="#7F646464" Height="43" Width="150"
    StrokeThickness="2" RadiusX="15" RadiusY="15"
    VerticalAlignment="Top" >
    <Rectangle.Fill>
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FFEE9D9D" Offset="0.197"/>
    <GradientStop Color="#FFFF7D7D" Offset="0.847"/>
    <GradientStop Color="#FFF2DADA" Offset="0.066"/>
    <GradientStop Color="#FF7E4F4F" Offset="1"/>
    </LinearGradientBrush>
    </Rectangle.Fill>
    </Rectangle>

  5. Switch back to Design View, either by clicking on the appropriate button on the upper right corner of the art board or choosing View|Active Document View|Design View from the menu bar.
  6. Right-click on the rectangle and click on Make Into Control.
  7. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  8. In the dialog box, choose Button, change the Name (Key) field to navButtonStyle and click OK.
  9. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  10. You are now in template editing mode. There are two on-screen indicators that you are in this mode: one is the Objects and Timeline tab:
  11. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  12. And one is the MainControl.xaml at the top of the art board:
  13. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  14. Click on the up button to exit template editing mode.
  15. Delete the button that our Rectangle was converted into.
  16. Select all the buttons in the StackPanel by clicking on the first one and then Shift+clicking on the last one.
  17. With all the buttons selected, go to the Properties tab, type Style into the search box.
  18. Using the techniques you’ve learned in this chapter, change the style to navButtonStyle, so that your screen now looks like this:
  19. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

    The result is still not quite what we’re looking for, but it’s close. We need to increase the font size again; fortunately, we know how easy that is in Blend.

  20. Click on one of the buttons and choose Object|Edit Style|Edit Current from the menu bar to get into style editing mode.
  21. Make note of all the visual indicators. In the Properties tab, change the FontSize to 18, the Cursor to Hand, the Height to 45, and the Width to 200. You should see the changes immediately. The cursor change will only be noticeable at run time.
  22. Exit the template editing mode.
  23. There is a slight problem with the last button; the font is a little too large. Click on the button and use the Properties tab to change the FontSize to 12.
  24. Run the project and your application will look something like this:
  25. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  26. Run your mouse over the buttons. The button no longer reacts when you mouse over it, we’ll fix that next.

What just happened?

We just took a plain old button and turned it into something a little more in line with the graphic designers’ vision but how did we do it?

When in doubt, look at the XAML
The nice thing about Silverlight is that you can always take a look at the XAML to get a better understanding of what’s going on. There are many places where things can “hide” in a tool like Blend or even Visual Studio. The raw naked XAML, however, bares all.

For starters, we took a chunk of XAML and, using Blend, told Silverlight that we wanted to “take control” over how this button looks. This data was encapsulated into a Style and we told all our buttons to use our new style. When the new style was created, we lost some of our formatting data. We then inserted it back in and added a few more properties.

If you’re really curious to see what’s going on, let’s take a closer look at the XAML that Blend just generated for us:

<Style TargetType="Button">
<Setter Property="FontSize" Value="18.667"/>
<Setter Property="Background" Value="Red"/>
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Margin" Value="5"/>
</Style>
<Style x_Key="smallerTextStyle" TargetType="Button">
<Setter Property="FontSize" Value="9"/>
</Style>
<Style x_Key="navButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle RadiusY="15" RadiusX="15" Stroke="#7F646464"
StrokeThickness="2">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FFEE9D9D" Offset="0.197"/>
<GradientStop Color="#FFFF7D7D" Offset="0.847"/>
<GradientStop Color="#FFF2DADA" Offset="0.066"/>
<GradientStop Color="#FF7E4F4F" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter HorizontalAlignment="{TemplateBinding
HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding
VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="24"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Height" Value="45"/>
<Setter Property="Width" Value="200"/>
</Style>

You’ll immediately notice how verbose XAML can be. We’ve not done a great deal of work, yet we’ve generated a lot of XAML. This is where a tool like Blend really saves us all those keystrokes. The next thing you’ll see is that we’re actually setting the Template property inside of a Setter node of a Style definition. It’s not until toward the end of the Style definition that we see the Rectangle which we started with. There’s also a lot of code here devoted to something called the Visual State Manager.

Prior to us changing the control’s template, you’ll remember that when you moved your mouse over any of the buttons, they reacted by changing color. This was nice, subtle feedback for the user. Now that it’s gone, we really miss it and so will our users. If you carefully study the XAML, it should come as no surprise to you that the button doesn’t do anything other than just sit there: we’ve not defined anything for any of the states listed here. The nodes are blank. Let’s do that now.

LEAVE A REPLY

Please enter your comment!
Please enter your name here