Posts Tagged ‘XAML’

Basic Windows Phone 7 Motion Design

2 Comments »

Click here if you don’t want to hear me complain about the Silverlight toolkit and you just want to get to the animations.

If you are like me, you’re working on Windows Phone 7 applications in your pajamas, subsisting on pork jerky and Coke Zero and dreaming of that one project that will make you richer than your wildest dreams while begging Dell to actually announce some kind of release date for the Dell Venue Pro.

But I suspect that we have less in common. In fact, the only thing we probably have in common is a desire to know how to actually replicate the Windows Phone 7 motion design.

That and our breathtaking good looks.

But back to the motion design. If you download the Silverlight Windows Phone toolkit source code, download and run it, you’ll see some animations that look kind of like the animations on the phone but not really. There are a couple of reasons for this.

Reason #1 – The easing functions have been placed on the wrong keyframes in the toolkit. They should be placed on the second keyframe, but they are on the first keyframe. This, of course, doesn’t make any sense since there is nothing to ease in the first keyframe, so I suspect it is some kind of transcription error.

Reason #2 – The easing function is an exponential one. Not a problem, pretty normal. But its exponent is 15. To give you a good idea of what that kind of “easing” looks like, here is the Blend representation of an exponent 15 easing:

image

It’s basically like cutting the animation time by two thirds. In contrast, here is the function with an exponent 5 easing:

image

Much ease-ier (get it?).


OK… enough about the Silverlight toolkit. You want to actually know how to write animations that approximate Windows Phone 7, right?

I currently have no phone, so I can’t study the animations in the closest detail (waiting for the Dell Venue Pro), but here is what I’ve gathered from the Silverlight toolkit and what I can see in the emulator:

“In” animations

When some UI component is appearing, we would use an “In” animation. “In” animations are a shade longer than “Out” animations. I assume this is to help the users’ eyes adjust to the new UI.

To the best of my knowledge, “In” animations:

  • are .35 seconds long
  • use exponential 5 easing

“Out” animations

When a UI component is exiting (either through navigation or due to the lack of need for it) we use an “Out” animation. Their shorter length leave the user with the impression of speed when they want to get to the next UI.

“Out” animations:

  • are .25 seconds long
  • use exponential 5 easing

OK… now on to some XAML:

Turnstile Animations:

This is when the screen-wide UI turns on its left-hand edge, such as when the user opens an application.

Turnstile Forward In

Turnstile Forward In
  1. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.Projection).(PlaneProjection.RotationY)”>
  2. <EasingDoubleKeyFrame KeyTime=”0″ Value=”-80″ />
  3. <EasingDoubleKeyFrame KeyTime=”0:0:0.35″ Value=”0″>
  4. <EasingDoubleKeyFrame.EasingFunction>
  5. <ExponentialEase EasingMode=”EaseOut” Exponent=”5″/>
  6. </EasingDoubleKeyFrame.EasingFunction>
  7. </EasingDoubleKeyFrame>
  8. </DoubleAnimationUsingKeyFrames>

Turnstile Forward Out

Turnstile Forward Out
  1. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.Projection).(PlaneProjection.RotationY)”>
  2. <EasingDoubleKeyFrame KeyTime=”0″ Value=”0″ />
  3. <EasingDoubleKeyFrame KeyTime=”0:0:0.25″ Value=”50″>
  4. <EasingDoubleKeyFrame.EasingFunction>
  5. <ExponentialEase EasingMode=”EaseIn” Exponent=”5″/>
  6. </EasingDoubleKeyFrame.EasingFunction>
  7. </EasingDoubleKeyFrame>
  8. </DoubleAnimationUsingKeyFrames>

Turnstile Backward In

Turnstile Backward In
  1. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.Projection).(PlaneProjection.RotationY)”>
  2. <EasingDoubleKeyFrame KeyTime=”0″ Value=”50″ />
  3. <EasingDoubleKeyFrame KeyTime=”0:0:0.35″ Value=”0″>
  4. <EasingDoubleKeyFrame.EasingFunction>
  5. <ExponentialEase EasingMode=”EaseOut” Exponent=”5″/>
  6. </EasingDoubleKeyFrame.EasingFunction>
  7. </EasingDoubleKeyFrame>
  8. </DoubleAnimationUsingKeyFrames>

Turnstile Backward Out

Code Snippet
  1. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.Projection).(PlaneProjection.RotationY)”>
  2. <EasingDoubleKeyFrame KeyTime=”0″ Value=”0″ />
  3. <EasingDoubleKeyFrame KeyTime=”0:0:0.25″ Value=”-80″>
  4. <EasingDoubleKeyFrame.EasingFunction>
  5. <ExponentialEase EasingMode=”EaseIn” Exponent=”5″/>
  6. </EasingDoubleKeyFrame.EasingFunction>
  7. </EasingDoubleKeyFrame>
  8. </DoubleAnimationUsingKeyFrames>

Slide Animations

We see these animations in things like creating new e-mails. They seem to be used when the user is doing some task that fits within the context of the screen they are already on. Slide animations use an opacity animation combined with a horizontal or vertical animation.

Slide animations use the same .25 seconds on animate out and .35 seconds on animate in and, according to the toolkit, the UI slides 200 pixels in whatever direction it is sliding.

Here is a sample Slide Up and Slide Down animation:

Slide Up Fade In animation

Slide Up Fade In
  1. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TranslateTransform.Y)”>
  2. <EasingDoubleKeyFrame KeyTime=”0″ Value=”200″ />
  3. <EasingDoubleKeyFrame KeyTime=”0:0:0.35″ Value=”0″>
  4. <EasingDoubleKeyFrame.EasingFunction>
  5. <ExponentialEase EasingMode=”EaseOut” Exponent=”5″/>
  6. </EasingDoubleKeyFrame.EasingFunction>
  7. </EasingDoubleKeyFrame>
  8. </DoubleAnimationUsingKeyFrames>
  9. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.Opacity)”>
  10. <EasingDoubleKeyFrame KeyTime=”0″ Value=”0″ />
  11. <EasingDoubleKeyFrame KeyTime=”0:0:0.35″ Value=”1″>
  12. <EasingDoubleKeyFrame.EasingFunction>
  13. <ExponentialEase EasingMode=”EaseOut” Exponent=”5″/>
  14. </EasingDoubleKeyFrame.EasingFunction>
  15. </EasingDoubleKeyFrame>
  16. </DoubleAnimationUsingKeyFrames>

Slide Down Fade Our animation

Code Snippet
  1. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.RenderTransform).(TranslateTransform.Y)”>
  2. <EasingDoubleKeyFrame KeyTime=”0″ Value=”0″ />
  3. <EasingDoubleKeyFrame KeyTime=”0:0:0.25″ Value=”200″>
  4. <EasingDoubleKeyFrame.EasingFunction>
  5. <ExponentialEase EasingMode=”EaseOut” Exponent=”5″/>
  6. </EasingDoubleKeyFrame.EasingFunction>
  7. </EasingDoubleKeyFrame>
  8. </DoubleAnimationUsingKeyFrames>
  9. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=”(UIElement.Opacity)”>
  10. <EasingDoubleKeyFrame KeyTime=”0″ Value=”1″ />
  11. <EasingDoubleKeyFrame KeyTime=”0:0:0.25″ Value=”0″>
  12. <EasingDoubleKeyFrame.EasingFunction>
  13. <ExponentialEase EasingMode=”EaseOut” Exponent=”5″/>
  14. </EasingDoubleKeyFrame.EasingFunction>
  15. </EasingDoubleKeyFrame>
  16. </DoubleAnimationUsingKeyFrames>

Coming soon… swivel animations and rotate animations… I’m not totally certain on what I’m seeing in the toolkit. It doesn’t seem to jive with what I’m seeing from the phone. I may wait a few days until I get a phone and can dissect the motion design a  little bit more closely.


Silverlight 4 Binding and StringFormat in XAML

25 Comments »

I discovered this amazing feature almost by accident and it has made this one part of my design so much easier that I had to share it.

A new feature in Silverlight 4 is the ability to using the StringFormat feature when binding. Previously, if I wanted to have a piece of text that said “Your name is [username]” I could either use the old Horizontal-Stack-Panel-And-2-TextBlocks trick (as seen below)…
<StackPanel Orientation=”Horizontal”>
<TextBlock Text=”Your name is” Margin=”0,0,4,0″/>
<TextBlock Text=”{Binding username}“/>

</StackPanel>

…or write a value converter (not going to be seen below because there’s a great example of it over here. Incidentally, that example is totally irrelevant if you’re going to use StringFormat, but more on that in a second).

The StringFormat option in Silverlight 4 allows you put all that information into a single field, which is extremely useful not only for TextBlocks, but for Content fields in a Button. In fact, let’s use that as an example.

Let’s say you want to create a Button to log out, so you want it to say “Log Out of <Username> Account”. (A bit clumsy, but the technique is the important part.) All you would have to do is the following:

<Button Content=”{Binding username, StringFormat=’Log Out of \{0\} Account’}“/>

This gets even better for things like number formatting. Let’s say we want the user to enter an amount of money (for example, $1,593.29) into a TextBox (maybe in a PayPal application). If we have bound that value to a numeric format, we can express that format through binding and when the TextBox loses focus, the StringFormat will take the number entered and format in a currency format.

<TextBox Text=”{Binding paymentAmount, StringFormat=\{0:C2\}}/>

The only issue with numerical and date formats is they the MUST be bound to a number or date.

With that in mind, here is a sampling of StringFormat options, stolen mostly from Kathy Kam. For more complete options, check out the MSDN articles on String.Format and trial-and-error your way through things. If you want to play around with this, download my StringFormat project or look at the Silverlight sample app at the bottom of this page.

Strings

For a string with the value “Silverlight”

Using \{0\,#\} effectively forces the string to be at least # characters long, using spaces to pad it to the requested length.

StringFormat=\{0\,20\} : “                  Silverlight”
StringFormat=\{0\,-20\} : “Silverlight                  ”
StringFormat=’I just typed &quot;\{0\}&quot;.’ : “I just typed “Silverlight”.”

MSDN article on Composite Formatting

Numbers

For a double with the value : “38293.53”

StringFormat=c : “$38,293.53” – Use ‘c’ for currency
StringFormat=e : “3.829353e+004” – Use ‘e’ for exponential (scientific)
StringFormat=n : “38,293.53” – Use n for number

You can also use these in the following format:

\{0:(letter)(number)\}

where (number) indicates how many decimal places there should be. The format will use standard rounding rules to determine the last digit. For example:

StringFormat=\{0:c0\} : “$38,294”
StringFormat=\{0:n4\} : “38,293.5300”
StringFormat=You have \{0:c1\} : “You have $38,293.5”

MSDN article for standard number formatting
MSDN article for custom number formatting

Dates

The date formatting has a huge range of options.

For the DateTime of “April 17, 2004, 1:52:45 PM”

You can either use a set of standard formats (standard formats)…
StringFormat=f : “Saturday, April 17, 2004 1:52 PM”
StringFormat=g : “4/17/2004 1:52 PM”
StringFormat=m : “April 17”
StringFormat=y : “April, 2004”
StringFormat=t : “1:52 PM”
StringFormat=u : “2004-04-17 13:52:45Z”
StringFormat=o : “2004-04-17T13:52:45.0000000”

… or you can create your own date formatting using letters (custom formats)

StringFormat=’MM/dd/yy’ : “04/17/04”
StringFormat=’MMMM dd, yyyy g’ : “April 17, 2004 A.D.”
StringFormat=’hh:mm:ss.fff tt’ : “01:52:45.000 PM”

MDSN article for standard date formatting
MSDN article for custom date formatting

Sample App


XAML Files for Location Visualizations in Silverlight and WPF

No Comments »

In the comments of my Silverlight unemployment visualization, someone asked about where I got the US outline. I got it from the WikiCommons website which has an SVG (scalable vector graphics) version that I pulled into Adobe Illustrator and then exported as a XAML file using Mike Swanson’s Illustrator-to-XAML plugin.

I realized this might not be possible for many people who don’t own Adobe Illustrator, so I did it myself for several files that are now available for download as XAML vector graphics maps of the US.

Download all Silverlight and WPF XAML files

Silverlight

WPF

I’ll confess, the real difference between the Silverlight and WPF files is that the WPF files encapsulate everything into a “Viewbox” control that allows dynamic resizing of the maps. If you want that functionality in Silverlight, just download and install the Silverlight toolkit and encapsulate the Canvas into a Viewbox. (The Viewbox will be a standard control in Silverlight 4, I am reliably informed.)

Now, a quick overview of the files:

United States Map with States

This is a nice tidy file (69K) with vector maps for all the states in the US. Each state has been named by its abbreviation. For example, the California map path would have the attribute: x:Name=”CA”.

United States Map with Congressional Districts

This file is based off of the Wiki Commons Congressional District map and is pretty big (about 1 MB). The paths are named based on a State_District naming convention. For example: Washington’s 8th Congressional District would have the attribute x:Name=”WA_8″.

There are 7 “at large” districts, which indicate states that only have one congressional seat. They have the attribute “State_At_Large“… for example, North Dakota’s one and only congressional district has the attribute x:Name=”ND_At_Large”.

United States Map with Counties (FIPS)

This map is pretty hefty at 1.5 MB. All paths have a FIPS code for the county they represent as their x:Name attribute. A FIPS code is a 5 digit code corresponding to a unique county in the United States. The first two digits indicate a state (for example, California is “06″) and the last three digits indicate a unique county (for example, Orange County in California is “059″). Because of the limitations in the XAML x:Name conventions, the FIPS code for a county is preceeded by an underscore. So, the path indicating Orange County, California would be x:Name=”_06509″.

If you need a FIPS-to-CountyName file, check out this FIPS code CSV file.

United States Map with Counties (County Names)

This is the same map as the FIPS map except that the x:Name attribute is State_CountyName. For example, the path for Fulton County, Georgia would have the attribute x:Name=”GA_Fulton”. Periods, commas and apostrophes have been deleted. Multiple word and hyphenated counties have an underscore where the space or hyphen would be. For example, Alaska’s Skagway-Hoonah-Angoon Borough would be x:Name=”AK_Skagway_Hoonah_Angoon”.

Holy cow, Alaska… did you really need to name a county with more letters than the number of people living there?

Anyway, that’s the overview of these files. In the interest of keeping the file size down (no, really! Stop laughing at me!), the county and congressional district boundaries aren’t as details as we might prefer, but that’s the trade-off we have. Also, the county name data is pretty good, but there are over 3100 counties in the US, so I didn’t get a chance to double check each one of the names. Use at your own risk.


Bookmarks for February 20th

1 Comment »

These are my links for February 20th:


Bookmarks for February 10th

No Comments »

These are my links for February 10th:


Bookmarks for February 10th

No Comments »

These are my links for February 10th:


XAML Intellisense for Blend

No Comments »

Karsten Januszewski has a post on getting intellisense into Blend. Apparently it only works for WPF (it “works” for Silverlight, but it pulls from the WPF XML schema, which sounds like it could be more confusing than useful).

I’ve been begging for this for a while. I’m glad to see it in there… its has easily been the biggest missing feature in an otherwise fantastic product.


Styling the ScrollViewer

2 Comments »

I recently got a comment asking if I could do something on creating a Blend-type ScollViewer styling. The only problem is that the ScrollViewer is a multi-post affair, which I’ll try to get completed in the next month or so. I’m going to go ahead and put up the basics here, much like my Styling the ComboBox and Styling the ListView posts.

In the meantime, I’m making available for download a Resource Dictionary with the Blend ScrollViewer style as I’ve approximated it. (You may have to right-click “Save As…” on that file since IE will do its darndest to open it up.) Just load the resource dictionary into your project and set

<ScrollViewer Template=”{DynamicResource BlendScrollTemplate}” />

Note: This is not the “real” Blend styles… just my rendition/approximation.

In the meantime, here’s the overview for the ScrollViewer. When you look at a template of the ScrollViewer (right-click on the ScrollViewer, got to “Edit Control Parts (Template) -> Edit a Copy…“) you should see something like this:

clip_image001[7]

If you want to change something about the main content area (highlighted below), you’re probably going after the PART_ScrollContentPresenter

clip_image001[11]

If you want to style the corner (highlighted below), look at changing the Corner Rectangle.

clip_image001[15]

If you want to style the HorizontalScrollBar and/or the VerticalScrollBar (highlighted below), you should right-click on either the PART_VerticalScrollBar or the PART_HorizontalScrollBar and go to “Edit Control Parts (Template) -> Edit a Copy…

clip_image001[13]

A point of note: Because of the way Blend works, it can be difficult to visually style a Vertical and Horizontal ScrollBar in the same Template. Don’t create another template. It’s a waste of time and will make your resources a pain to navigate. I’ll go over exactly what to do in a little bit.

The ScrollBar template should look something like this:

clip_image001[9]

If you want to style the ScrollBar thumbs (the bars you would drag to scroll, highlighted below), you’ll need to change the template for the “Thumb” in the PART_Track. Note: Unless you’re doing something really complex, you should only need to style the Thumb control one time. You don’t need different styles for the vertical and the horizontal.

clip_image001[17]

If you want to style the directional buttons (highlighted below), you will need to change the templates for the first and last “RepeatButton” controls (the ones that aren’t in the PART_Track) using the right-click -> Edit Control Parts (Template) -> Edit Template. (This template should already be copied into your resources.) Again, unless you’re doing something complex, you should only need to style this button one time.

clip_image001[19]

If you want to style the empty area that allows for fast scrolling, you will need to change the style for the two RepeatButtons in the PART_Track (DecreaseRepeatButton and IncreaseRepeatButton)using the right-click -> Edit Control Parts (Template) -> Edit Template. You should only need to do this one time and then apply that style/template across the all the instances of this button.

clip_image001[21]

Over the next couple weeks, I’ll try to put up posts going over how to style all of these into the Blend style. I’ll update this post pointing to the more in-depth tutorials as I go along. Until I get around to doing that, feel free to download the ResourceDictionary with the Blend styles in them.


How Do I Make a ListView or a ScrollViewer Left Handed?

6 Comments »

Several months back, I was doing some work for a company that was using WPF for a stylus based application. One of the things that they found they needed was a scrollbar that could be used by left handed people who would have to cover the entire screen with their left hand in order to scroll a traditional scroll viewer.

The solution ended up being so easy in WPF that I thought I’d post it here.

I’m in a two-birds-one-stone mood, so we’ll do this for both the listview, which will also cover a more traditional scrollviewer. Let’s start with our ever friendly listview.

NormalListViewAt the very sight of this thing, with a stylus in hand, your average lefty is thinking to him or herself “I wonder if I can do my work upside down?” Let’s show them that we love and accept them just as they are.

The first thing we’re going to do is create a new template for this sucker, so right click on your listview and go to “Edit Control Parts (Template) -> Edit a Copy…

Lefty_EditControlParts

Now we’re looking at the standard listview template. Mine looks like this:

ListViewTemplateLet’s dig right into the ScrollViewer. If you’re doing this from the listview (like I am) then creating a template for the listview has already created a template for the scrollviewer. If you’re starting from a basic scrollviewer, you can pretty much start right here.

For the purposes of making this thing easy to work with in Blend, go ahead and set the HorizontalScrollBarVisibility and VerticalScrollBarVisibility to Visible.

 ScrollBar_Visibility

And then “Edit Control Parts (Template) -> Edit a Copy…” (or “Edit Control Parts (Template) -> Edit Template” if it is available).

We are now looking at the guts of the ScrollViewer Control.

ListView ScrollViewer will look like this:

ListViewScrollTemplateThe normal ScrollViewer will look like this:

 NormalScrollViewer

For our purposes, they’re functionally the same. It is actually a fairly simple control… basically just a Grid panel with the columns and rows set up like so:

<Grid.ColumnDefinitions>
      <ColumnDefinition Width=”*/>
      <ColumnDefinition Width=”Auto/>
</Grid.ColumnDefinitions>

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

The scrollBars are set up so that their visibility is tied to (duh) the visibility that is set on the control. But what this does is it means that when they are collapsed… they Grid reclaims the space that they were taking up.

Now… here’s the hilarious part… in order to make this ScrollViewer left handed, all you have to do is swap the Grid.Columns:

<Grid.ColumnDefinitions>
      <ColumnDefinition Width=”Auto/>
      <ColumnDefinition Width=”*/>
</Grid.ColumnDefinitions>

You’ve now switched the columns so that the left handed column is auto. Here’s a list of the Grid.Column realignments you’ll need to make:

Change Column to “1″:

Lefty_Column1

  • PART_HorizontalScrollBar
  • All DockPanels (ListView only)
  • PART_ScrollContentPresenter (ScrollViewer only)
  • Corner (ScrollViewer only)

Change Column to “0″:

Lefty_Column0

  • PART_VerticalScrollBar

Basically, swap everything from in the two columns.

Done.

FinalLeftyListViewIf you want to make this a more robust control, I recommend creating a ScrollViewer with an additional dependency property (IsSouthPaw or something). Make it so that your Grid has three columns:

<Grid.ColumnDefinitions>
      <ColumnDefinition Width=”Auto/>
      <ColumnDefinition Width=”*/>
      <ColumnDefinition Width=”Auto/>

</Grid.ColumnDefinitions>

And then you can just create a trigger that swaps the column placement of your PART_VerticalScrollBar. Such a trigger will look something like this. And by “something”, I mean “exactly”.

<Trigger Property=”IsSouthPawValue=”True>
      <Setter Property=”Grid.ColumnTargetName=”PART_VerticalScrollBar“  Value=”0/>
</Trigger>

Go forth and make Ned Flanders proud.

By the way, I listen to pop punk whenever I write my tutorials and I just thought I should let Senses Fail know that they can probably get away with about 80% less “dying cat” screaming and still put out good music. You know… because they’re probably WPF programmers on the side and they’ll probably read this to solve all their left-handed scrollbar needs.


WPF Designers Guide to Styles And Templates

4 Comments »

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)

Follow me: matthiasshapiro