Archive for the ‘styles’ Category.

New Silverlight Posts at Veracity Blogs

I’ve started a series of posts on Silverlight and other topics over at the Veracity Solutions Blog.

Veracity Solutions is the software consulting firm where I work and we’ve decided that it would be a good idea to do some sponsored posting there.

Blog posts up so far are:

More are coming, including tutorials on behaviors and paths.

How To Create An Animated ScrollViewer (or ListBox) in WPF

UPDATED 05/22/09

In the comments, someone mentioned that the project wasn’t working properly for keyed scrolling. I’ve updated the project with:

  • Key scrolling (left, right, up, down, page up, page down)
  • CanKeyboardScroll property on the AnimatedScrollViewer so that keyboard scrolling can be turned off
  • ScrollToSelectedItem property on the AnimatedListBox so that the user can have it automatically scroll to a ListBoxItem

That last one is a little hacky… I use the ListBox ItemContainerGenerator to get the heights of all the items up to the one you want and then scroll it that. I’m almost positive there is a better way and if anyone knows what it is, I’d love to hear it.

First things first, here are the project files.

Animated ScrollViewer and ListBox Project Files (Updated 5/22/09) – Contains the AnimatedScrollViewer control library with AnimatedScrollViewer and AnimatedListBox

Animated ScrollViewer and ListBox DLL (Updated 5/22/09) – For those of you who don’t care how it works and just want it to work

OK… this is going to be something of a whirlwind since I’ve never written a post this in-depth before… it will strain the limits of my ADD.

Problem:

The Listbox/ScrollViewer not only doesn’t animate, but it seems impossible to tweak it so that it animates.

The Reason:

The reason has everything to do with the ScrollViewer. Basically, the ScrollContainer and the ScrollBars are very tightly intertwined. There is a lot of code that does all the scrolling calculations and that code needs to apply to the scrolled content as well as the UI for the ScrollBars. If you dig deep enough, you’ll see the reasons. Reasons which I assume for the moment you don’t care about… you’re probably in more of a “make the @#&($ thing work!” mood. I know I was.

The Solution:

My solution was basically to completely bypass the built-in ScrollBars and put in new ScrollBars with new logic. They look and act just like normal ScrollBars, so you should be able to style them just you would any normal ScrollViewer.

OK… how I did it. (I’m going to use both Blend 2 and Visual Studio 2008)

First, create a new custom control for WPF. This can be done by going into Visual Studio and creating a new Project. Select “WPF Custom Control Library”

clip_image001[7]

In Blend:

 clip_image001[9]

Add a WPF application to the project too so you have something to test. In the WPF application, get Blend to generate the default template for a normal ScrollViewer, accessible (in Blend) by putting a ScrollViewer into the project and right-clicking on it and selecting “Edit Control Parts (Template) –> Edit a Copy…”

clip_image001

Once have the default ScrollViewer template, select the “PART_VerticalScrollBar” and the “PART_HorizontalScrollBar” and copy and paste them. Rename your new ScrollBars something you like… I used “PART_AniVerticalScrollBar” and “PART"_AniHorizontalScrollBar”. Now, set the Visibility of the original ScrollBars to “Collapsed”. (We can’t get rid of them, because the ScrollViewer will be looking for them and will throw a conniption if it can’t find them.)

Also, change the Value of your new ScrollBars to 0. You’ll probably have to click on the orange box next to Value and select “Reset”.

clip_image001[11]

In Visual Studio, right-click on your WPF Custom Control project and go to “Add –> New Item…” . Then select “Custom Control (WPF)” and name it something you like (mine is named AnimatedScrollViewer). This should add a class to your project as well as a basic template to your Generic.xaml file.

Copy the ScrollViewer template that we just made and paste it into the Generic.xaml. The only change we need to make is to change:

TargetType="{x:Type ScrollViewer}"

to

TargetType="{x:Type local:AnimatedScrollViewer}"

in the Style and the ControlTemplate.

OK… that’s pretty much it with the XAML. Now we get to move into the code.

Right now, our class inherits from Control, but we want it to inherit from ScrollViewer like so:

public class AnimatedScrollViewer : ScrollViewer

Next get some containers for our new spiffy ScrollBars so that we can access them from the custom control code. Type the following before the class:

[TemplatePart(Name = "PART_AniVerticalScrollBar", Type = typeof(ScrollBar))]
[TemplatePart(Name = "PART_AniHorizontalScrollBar", Type = typeof(ScrollBar))]

and the following just inside the class:

ScrollBar _aniVerticalScrollBar;
ScrollBar _aniHorizontalScrollBar;

Now, we’ll override the OnApplyTemplate and make the connection between the template scrollBars and our class ScrollBars:

public override voidOnApplyTemplate()
{
    base.OnApplyTemplate();

    ScrollBar aniVScroll = base.GetTemplateChild("PART_AniVerticalScrollBar") asScrollBar;
    if(aniVScroll != null)
    {
        _aniVerticalScrollBar = aniVScroll;
    }
    _aniVerticalScrollBar.ValueChanged += newRoutedPropertyChangedEventHandler<double>(_aniVerticalScrollBar_ValueChanged);

    ScrollBar aniHScroll = base.GetTemplateChild("PART_AniHorizontalScrollBar") asScrollBar;
    if(aniHScroll != null)
    {
        _aniHorizontalScrollBar = aniHScroll;
    }
    _aniHorizontalScrollBar.ValueChanged += newRoutedPropertyChangedEventHandler<double>(_aniHorizontalScrollBar_ValueChanged);

    this.PreviewMouseWheel += newMouseWheelEventHandler(AnimatedScrollViewer_PreviewMouseWheel);
}

Before we address the three event handlers we added, we need to create the Dependency Properties with which they will be futzing.

(We’re going start going a little bit faster. Please download the code for the excruciating detail.) We need to add the following Dependency Properties. I’m using a “PropertyName (type)”.

Dependency Properties

ScrollingTime (TimeSpan) – This will be an easy way to change the speed of the scrolling. I created mine to default at half a second, but if you changed it to 0 seconds, it would act just like any normal ScrollViewer.

ScrollingSpline (KeySpline) – This property along with the ScrollingTime property is meant to give designers and developers the easiest control possible over the animation. This property describes the spline along which the scrolling will animate. If you don’t know what this means, just leave it alone, you’ll be fine.

TargetVerticalOffset (double) and TargetHorizontalOffset (double) – These are properties that tell the ScrollViewer where it will be animating to. In the PropertyChangedCallback, they kick off a method that starts the animation.

VerticalScrollOffset (double) and HorizontalScrollOffset (double) – For some reason the normal VerticalOffset and HorizontalOffset properties in a ScrollViewer are not capable of animation. So I wrote these properties that can be animated using standard storyboard procedures. If you use them to animate, make sure you also change the TargetVerticalOffset and TargetHorizontalOffset stuff as well… otherwise there will be a disconnect between the two.

Event Handlers

CustomPreviewMouseWheel event handler – This grabs any mouse wheel spinning and uses it to change the TargetVerticalOffset so that the ScrollViewer will still animate the scrolling when the mouse wheel spins.

VScrollBar_ValueChanged and HScrollBar_ValueChanged event handlers – These are called whenever the the ScrollBars are interacted with. There was a really weird problem with some of the interaction (the arrow keys and fast-scrolling buttons weren’t working properly), so these handlers hold logic to try to translate the weirdness into something viable. They then set the Target_Offset properties appropriately.

Methods

animateScroller – This method builds the animation programmatically based off of the appropriate properties and runs it.

And that’s really about it. Once you have the AnimatedScrollViewer working, you can just add use it inside your ListBox templates and it should work. (For those who are averse to doing such a thing, I’ve added extremely simple AnimatedListBox.)

Using the "Tag" Field And Triggers To Avoid Writing a Value Converter in WPF

I was working on a project recently and I wanted one of my layout controls to have a different margin based on a certain piece of data.

(It’s a long story… let’s just say that this is a good post if you want to change properties of a control based on a piece of data of a different type.)

So… for the sake of the argument, let’s say that I want my control to have a margin of “4,4,4,4″ if my data returns “dog” and I want it to have a margin of “2,2,2,2″ if my data returns “cat” and a margin of “0,0,0,0″ if the data is anything else.

Normally, I would use a value converter for this. My problem was that I was sick of using value converters for things so specific and using them only a couple times in my application. So I decided I wanted to do this one with styles and triggers.

First thing I did was bind my data to the “Tag” field.

<Border Style=”{DynamicResource MyBorderWithTriggers}” Tag=”{Binding MySpecialData}” >

Then, I created a style for my Border layout control. If you’re in Blend, go to Object –> Edit Style –> Create Empty…

clip_image001

Create a new property trigger by clicking on the “+ Property” button and change the property to “Tag”.

clip_image001[5]

I couldn’t find a way to type “dog” into the field value, so I did it in the XAML (full XAML sample below, for those of you who want to cut to the chase… you know who you are).

With the property trigger highlighted, you’ll see a “Trigger recording is on” sign in the corner of your canvas.

clip_image001[7]

Just change all the properties you want. Of course, in this case, I’m just going to change the Margin property. If we do the same thing for the “Cat” contingency, we get the following style.

<Style x:Key=”MyBorderWithTriggers” TargetType=”{x:Type Border}”>
        <
Setter Property=”Margin” Value=”0,0,0,0″/>        <Style.Triggers>
                <Trigger Property=”Tag” Value=”Dog”>
                        <Setter Property=”Margin” Value=”4,4,4,4″/>
                </Trigger>
                <Trigger Property=”Tag” Value=”Cat”>
                        <Setter Property=”Margin” Value=”2,2,2,2″/>
                </Trigger>
        </Style.Triggers>
</
Style>

And we end up with a layout that changes its properties based on a bound value. And we don’t have to write endless value converters.  Pretty handy… or at least I thought so.

How To Use a ListView or DataGrid In a ComboBox Drop Down (Without A Line Of Code)

Super cool new thing I learned today. In WPF, we can make it so that the drop down (popup) on a ComboBox displays the data in a ListView. Because of the fact that I believe the DataGrid will eventually overtake the ListView as the gold standard for data display in WPF, we’ll do it both ways.

This tutorial is done entirely in Blend and without a line of code.

Step 0) (for the DataGrid only)

Go to Code Plex and download the WPF Toolkit. Extract to a convenient location.

Right-Click on the References folder in your project tab and click “Add Reference…”

clip_image001

Navigate to the location you extracted the WPFToolkit.dll file, select it and hit OK.
clip_image001[6]

Step 1) Select the ComboBox you wish to change and edit the ControlTemplate by right-clicking and selecting “Edit Control Parts (Template) –> Edit a Copy…”

clip_image001[1]

Step 2) Find the ItemsPresenter. This is what would normally display our ItemsSource.

clip_image001[3]

We’re going to get rid of it. And the ScrollViewer for good measure.

Step 3) Where the ScrollViewer is, put in a ListView or a DataGrid, whichever one you’re using.

clip_image001[5]

Now, go the properties of that ListView or DataGrid and click on the box to the right of “ItemsSource”

clip_image001[11]

and, in the resulting menu, select “Template Binding –> ItemsSource”.

clip_image001[7]

Set the DataContext of the ListView or DataGrid to the DataContext of the parent ComboBox using the same process.

And… you’re done! Open the ComboBox and you will see that you can select items in the ListView or DataGrid in the ComboBox dropdown and see those items change the selection of the ComboBox.

clip_image001[13]

You’ll notice that this is probably not yet an ideal solution. For example, when we select an item, the dropdown doesn’t automatically close. Your best bet is to use the SelectionChanged event to trigger some logic to close the ComboBox dropdown.

Create a Zooming Button Style In Silverlight Without Code

Download code for this sample (updated for RCW)

I was reading Mike Snow’s blog and he had a recent Silverlight tutorial on creating a Zooming toolbar. I looked at it and said to myself, “I think I can do that without code in Blend!” So here’s a tutorial on exactly that.

End product :

Big bonuses to this XAML-only method include:

  • Much smoother animation
  • Midway animation (if you fly over a button, it doesn’t need to animate all the way up before it starts to animate back down)
  • Really low overhead
  • Can be done and maintained entirely by a designer in Blend without any code

1) create a new Silverlight project in either Visual Studio 2008 or Blend 2.5.

2) In Blend, add a new folder for our images by right-clicking on the project and selecting “Add New Folder”

clip_image001

3) Pull in our images by right-clicking on our new folder and selecting “Add Existing Item…” Navigate to the images you want to use and select “OK” to bring them into the project.

clip_image001[4]

4) Create the button to which you want to add the image and then double-click it in the Obejcts and Timeline pane so that it has a yellow outline around it.

clip_image001[6]

5) Now, go to the image you want to insert (in the Project panel), right click on it and select “Insert”

clip_image001[8]

OK… so now we have a button with an image in it. Now it’s time to make the sucker zoom.

6) Right click on the button and select “Edit Control Parts (Template) -> Edit a Copy…”

clip_image001[10]

Name your custom Template and hit OK

clip_image001[12]

7) In the “States” pane, you see a set of “CommonStates” (Normal, MouseOver, Pressed, and Disabled). Click on the MouseOver state and a red box will surround your composition, indicating that any changes made will be changes to the “Mouse Over” state, not to the default control.

clip_image001[14]

Recording state:

clip_image001[16]

8] Click on the highest level item in the template (in my case, it is a “Grid”) and go to the “Transform” section in the “Properties” pane and select the “Scale” transformation tab. Change the X and Y scales to “1.5″

clip_image001[18]

If you run the project now, you’ll notice that we get a cool zoom in effect on the mouse over, but our zoom out when the mouse leaves the button is basically a snap back to the original size. Let’s fix that now.

9) Click on the the arrow icon in the MouseOver state in the States pane and select the “MouseOver -> Normal”

clip_image001[20]

In the “Transition Duration” box, type “.2″

clip_image001[24]

10) Extra Designer Happiness Bonus Step! – If you’d like to have a zoom effect that isn’t strictly linear, open up the timeline view with the button on the right hand of the state recording box (seen below).

clip_image001[26]

Click and drag the keyframe (the light gray oval below) to the point you want it. I put mine at .3 seconds.

clip_image001[28]

With the keyframe selected, you should see an “Easing” pane on the right. The default easing is linear (aka. no easing), but you can change the easing curve by just dragging the yellow dots. Here is the easing curve I’ve found works pretty well for my apps.

clip_image001[30]

That’s it. Now you can just assign this template to a button and you’ll have this zooming functionality all set up.rcw_zooming_button

Styling a Silverlight ScrollViewer (to Look Like a Mac ScrollViewer)

Mac Scroller Project Files Updated for RCW

Just because we’re working in Microsoft technologies doesn’t mean we can’t throw a bone to our Mac friends. After all, they are the people we love, our cousins and our neighbors, and that irritating guy who is dating our daughter and can’t seem to shut up about how awesome his Mac is even though he’ll be long out of his program in musical costume design before he ever pays off his laptop …

Issues? I don’t have issues. Why do you ask?

Anyway, since Silverlight is a semi-ubiquitous technology, it would be nice if we could cater to all platforms and not make anyone feel left out. And nothing makes people feel more left out than when they expect their application to work one way and it doesn’t.

So, here’s a picture of what we’re going for.

clip_image001

As far as I’m concerned (and therefore as far as this tutorial is concerned) the important stuff is to make sure that the incremental buttons (the arrow buttons in the bottom right) are in the right place. We can deal with the color later.

OK, so let create our ScrollViewer (I’ll be using Blend exclusively for this). I tossed a button in it and made it small so we can see both of the ScrollBars.

clip_image001[4]

Right click on the ScrollViewer in the “Objects and Timeline” section and go down to “Edit Control Parts (Template) -> Edit a Copy…”

clip_image001[6]

You should have something that looks like this:

clip_image001[8]

Let’s do the VerticalScrollBar first. Right click on it and go to “Edit Control Parts (Template) -> Edit a Copy…” Name it something memorable and you should get something like this:

clip_image001[12]

This is actually easier than it looks. The unnamed rectangles and the path lay down the basic visual backbone for the ScrollBar and the rest of it runs like this:
clip_image001[14]
VerticalSmallDecrease – The up button
VerticalLargeDecrease – The space between the up button and the VerticalThumb
clip_image001[16]
VerticalThumb – The interface element that allows the dragging interaction of the scrollbar
VerticalLargeIncrease – The space between the down button and the VerticalThumb
clip_image001[18]
VerticalSmallIncrease – The down button

The horizontal root in this template is strikingly similar.

So, let’s start by moving the VerticalSmallDecrease button down to the bottom above the VerticalSmallIncrease button. The magic here will happen in the VerticalRoot grid. (I highly recommend the Design/XAML split view for this one.) In the design view, our grid looks like this:

clip_image001[20]

Ugly. However, in the XAML, it looks like this:

<Grid.RowDefinitions>
<
RowDefinition Height=”Auto”/>
<RowDefinition Height=”Auto”/>
<
RowDefinition Height=”Auto”/>
<
RowDefinition Height=”*”/>
<
RowDefinition Height=”Auto”/>
</
Grid.RowDefinitions>
<
Grid.ColumnDefinitions>
<
ColumnDefinition/>
<
ColumnDefinition/>
</
Grid.ColumnDefinitions>

Much easier. For the purposes of maintaining a coherent structure, drag the VerticalSmallDecrease in Objects and Timeline pane until it is between the VerticalSmallIncrease and the VerticalLargeIncrease. Next, change the third RowDefinition to “*”. You can do this in the XAML or by clicking on the “Auto” iconimage until it becomes a “*” icon. image Change the fourth RowDefinition from “*” to “Auto”. When you do this, it won’t immediately act like an “Auto”. This is because Blend gives it an automatic “MinHeight” of whatever the current Height is. You can change that in the XAML (easiest move) or you can highlight that row by clicking just below the “Auto” icon until the row highlights in a semitransparent gray like so.

clip_image001[28]

You may need to zoom in to do this. Once highlighted, the properties of the Row will show up in the Properties tab on the right. Change the MinHeight to 0.

clip_image001[32]

Now we’ll need to change the Grid.Row properties of almost everything. Click on the items in the Objects and Timeline and change the Row property in the Layout section of the Properties tab like so:

VerticalLargeDecrease -> Row = 0
VerticalThumb -> Row = 1
VerticalLargeIncrease -> Row = 2
VerticalSmallDecrease -> Row = 3
VerticalSmallIncrease -> Row = 4

You’re done. With the Vertical part of the ScrollBar at least. You can do the same thing with the Horizontal part of it. Just move around the buttons, change the ColumnDefinitions and update the Column assignments. My best recommendation is to go back to the ScrollViewer template and assign your new ScrollBar template to the HorizontalScrollBar and then go back to editing the template from there.

clip_image001[34]

Later on…

After a bunch of color tweaking, I have a scroll viewer in silverlight that looks like this:

clip_image001[36]

I’m feeling OK with it. I’ve embedded what I have at this point below.

How to Assign ColumnHeaderContainerStyle and ColumnHeaderTemplate to a ListView Style

This is just a quick note on creating a ListView style with the appropriate GridView style and template assignments.

Normally, I’ve been creating listviews that look like this:

<ListView x:Name=”MyListView”
               ItemContainerStyle
=”{DynamicResource MyListViewItemContainerStyle}”>
   
<ListView.View>
        
<GridView ColumnHeaderContainerStyle=”{DynamicResource MyListViewHeaderStyle}”
                        
ColumnHeaderTemplate=”{DynamicResource MyGridColumnHeaderTemplate}”> 

I did this because I didn’t know exactly how to assign these styles and templates to the ListView Style. In the style, ColumnHeaderContainerStyle and ColumnHeaderTemplate are not properties of the ListView, they are properties of the GridView… which you can’t create a style for.

Instead, you can encapsulate all the information above in the following style.

<Style x:Key=”CustomListViewStyle” TargetType=”{x:Type ListView}”>
      <
Setter Property=”GridView.ColumnHeaderContainerStyle” Value=”{DynamicResource MyListViewHeaderStyle}” />
     
<Setter Property=”GridView.ColumnHeaderTemplate” Value=”{DynamicResource MyGridColumnHeaderTemplate}” />
     
<Setter Property=”ItemContainerStyle” Value=”{DynamicResource MyListViewItemContainerStyle}” />
</Style>

Problem solved.

WPF Designers Guide to Styles And Templates

This is a post that has taken months to complete, but addresses something that I don’t think I’ve seen sufficiently covered for anyone who is new to WPF. Resultantly, we’re going to go through it slowly and I’m officially begging for additional questions at the end.

Part of the problem with styles and templates in WPF stems from the fact that Blend allows a wonderfully simply way of creating a copy of a template:

SNT_EditControlParts

It then gives you something that looks like this:

<Style x:Key=”My_TemplateTargetType=”{x:Type Button}>
      <Setter Property=”Template>
            <Setter.Value>
                  <ControlTemplate TargetType=”{x:Type Button}>
                        <!– blah blah blah –>

So, from a usability point of view… I told it to create a Template and it created a style. I judged from this that styles and templates were roughly the same thing.

And I was confused.

So, first, I’ll try to explain styles and templates by explaining how they work and then I’ll draw an analogy that I hope is helpful.

Let’s say you have a button.

Hi_Button

You can change all sorts of properties of that button… visibility, background, width, height, margins, border thickness, alignment, font, whatever.

If you have a dozen buttons and you want them all to have the same properties, you can create a button style that specifies those properties and assigns them across the board. You can edit a style in Blend by selecting your control, clicking in the menu: “Objects -> Edit Style -> Edit a Copy…“.

Style editing in the objects tab will look like this.

Style_Objects

As you can see, there are no objects in the visual tree to play with… only properties to assign in the properties tab.

Button_Style_Properties

When you assign a property in Blend, your styles will save that assignment as setters and values. Let’s say we wanted all of our buttons to have green 18 point font  bold text. We could create a style that looked like this:

<Style x:Key=”GreenBorderButtonTargetType=”{x:Type Button}>
      <Setter Property=”ForegroundValue=”#FF00FF00/>
      <Setter Property=”FontSizeValue=”18 />
      <Setter Property=”FontWeightValue=”Bold/>
</Style>

The styles can only define properties that belong to the control type that they are styling (which is defined in the “TargetType“). Also, styles can only give information for properties the control already has and only in the way that the control is already set up. For example, because there is no property for changing the corner radius of a button, you can’t change the corner radius of a button using a button style.

However, what if we want to change something about the button that we can’t change with the given properties? For example, let’s say we wanted to see all the text show up twice.

Double_Button

In order to do this, we need to make what I’m going to call “structural changes” to our control. Structural changes are changes in the actual guts of the control, changes to the base elements that make up the control. For this we need a control template.

Boiled down to their essence, templates are little chunks of XAML that are inserted whenever you use your control. When you right click on something and go to  “Edit Control Parts (Template) -> Edit a Copy…“, Blend takes the default XAML that makes up your control and places it in the resources so that you can change it at your whim.

You can get to the Control Template using the right-click method described at the top of this post. Your basic button template will look something like this:

Button_Template

<Style x:Key=”MyButtonStyleTargetType=”{x:Type Button}>
      <Setter Property=”TemplateValue=”{DynamicResource MyButtonTemplate}/>
</Style>

<ControlTemplate x:Key=”MyButtonTemplateTargetType=”{x:Type Button}>
      <Microsoft_Windows_Themes:ButtonChrome x:Name=”Chrome>
            <ContentPresenter />
      </Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>

We can go in and add an additional ContentPresenter in here, like so:

<ControlTemplate x:Key=”MyButtonTemplateTargetType=”{x:Type Button}>
      <Microsoft_Windows_Themes:ButtonChrome x:Name=”Chrome>
            <Grid>
                  <Grid.RowDefinitions>
                        <RowDefinition Height=”.5*/>
                        <RowDefinition Height=”.5*/>
                  <Grid.RowDefinitions>
                  <ContentPresenter Grid.Row=”0/>
                  <ContentPresenter Grid.Row=”1/>
            </Grid>
      </Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>

And now our button shows all the content twice, one right on top of another.

The best way I’ve found to think about it is to think of your control as a car.

The dealer give the buyer a list of things that they can change about the car… interior color, leather or fabric seats, 4 or 6 cylinder engine… these are properties of the car… defined in the car “style”. (Basically, you can think of everything that you’re allowed to tweak at this website as the style of the car.)

<Style x:Name=”MySpecialCarTargetType=”{x:Type Camry}>
      <Setter Property=”ExteriorColorValue=”Blue/>
      <Setter Property=”TransmissionTypeValue=”5SpeedManual/>
</Style>

Camery_Basic
 
But let’s say that the buyer doesn’t want a normal seat… she wants a big comfy chair in place of the regular drivers seat. This is something outside of the scope of the list of things she was allowed to choose from, so they have to draw up new blueprints for making this new car. They have to create a new car “template”.

If our normal Camry blueprint looks like this:

<ControlTemplate x:Key=”MySpecialCarBlueprintTargetType=”{x:Type Camry}>
      <CamryFrame x:Name=”CamryFrame>
            <Seat Type=”Drivers/>
            <Seat Type=”FrontPassenger/>
            <Seat Type=”BackBench/>
      </CamryFrame>
</ControlTemplate>

We can go in and replace :

<Seat Type=”Drivers/>

With

<Seat Type=”ComfyChair/>

ComfyChair

You may also notice that, with this model we could get rid of all the other seats except the drivers seat or we could add 12 new rows of seats. We can change anything about the car because we’re down into the original car blueprint.

This is the basic difference between styles and templates.

  • A style is a list of properties that can be assigned in bulk to a control.
  • A template goes a big step further and actually defines the underlying structure of the control.

You may be asking: “So how do these two work together? And what is this Data Template think I keep hearing about?”

Given that this post is getting dangerously long already, I’m going to address those issues in a couple more posts on styles and templates.

I’ll end on this note: if you are working in WPF and you’re having trouble with styles and templates, please read all of these posts (as I get to them) and ask questions in the comments section. I’m pretty good about getting to the comments questions and if the question is big enough, I’ll write a whole post on it. There are few things more vital to a WPF developer/designer than to have a firm grasp on styles and templates. It is in this understanding that the power of WPF really comes out.

  • Who’s The Boss? Property Priority in Styles and Templates (coming soon)
  • Create Conditional Styles and Templates (With the Magic of Triggers) (coming soon)
  • So How Do Data Templates Fit Into All This? (coming soon)