Be Careful When Using Implicit Styles in WPF

by Shawn Duggan on 12/09/2009

I’m currently working on a WPF application that makes use of the newly released WPF Ribbon control.  My main window is laid out with a grid at its root; the first row containing the ribbon and the second row containing a few vertical StackPanels.  Everything was going well.

Each StackPanel I gave a border.  I decided to create a style to apply to them.  Expression Blend makes this a snap – I went with implicit styles like below.

   1: <ribbon:RibbonWindow.Resources>
   2:     <ResourceDictionary>
   3:         <Style TargetType="Border" >
   4:             <Setter Property="Border.BitmapEffect">
   5:                 <Setter.Value>
   6:                     <DropShadowBitmapEffect/>
   7:                 </Setter.Value>
   8:             </Setter>
   9:             <Setter Property="Border.CornerRadius" Value="10,10,10,10"/>
  10:             <Setter Property="Border.Padding" Value="5"/>
  11:             <Setter Property="Border.Margin" Value="10"/>
  12:             <Setter Property="Border.Background">
  13:                 <Setter.Value>
  14:                     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  15:                         <GradientStop Color="#FFAEBECE" Offset="0"/>
  16:                         <GradientStop Color="#FFD7E7F7" Offset="1"/>
  17:                     </LinearGradientBrush>
  18:                 </Setter.Value>
  19:             </Setter>
  20:         </Style>
  21:         <Style TargetType="{x:Type StackPanel}">
  22:             <Setter Property="Margin" Value="5"/>
  23:         </Style>
  24:         <ResourceDictionary.MergedDictionaries>
  25:             <ResourceDictionary Source="/RibbonControlsLibrary;component/Themes/Office2007Blue.xaml"/>
  26:         </ResourceDictionary.MergedDictionaries>
  27:     </ResourceDictionary>
  28: </ribbon:RibbonWindow.Resources>

What that means is that the style’s TargetType is set to a specific kind of control.  In my case that meant each of my StackPanel’s borders did not need to specify a style – they would simply get this one.  I was quite surprised to see my screen output look like this:

implicitstyles1

You can see that the borders are messed up on the left as well as along the right side.  I spent a lot of time, but couldn’t figure it out.  Everything looked ok.  By adding and removing my borders from the StackPanels I knew they were the culprit…but how?

I decided to try using the style in the traditional sense, by giving it a name and applying it to each border in the xaml.  This resulted in markup like the below (sections cut out for brevity).

   1: <ribbon:RibbonWindow.Resources>
   2:     <ResourceDictionary>
   3:         <Style TargetType="Border" x:Key="StackPanelBorder">
   4:             <Setter Property="BitmapEffect">
   5:                 <Setter.Value>
   6:                     <DropShadowBitmapEffect/>
   7:                 </Setter.Value>
   8:             </Setter>
   9:             <Setter Property="CornerRadius" Value="10,10,10,10"/>
  10:             <Setter Property="Padding" Value="5"/>
  11:             <Setter Property="Margin" Value="10"/>
  12:             <Setter Property="Background">
  13:                 <Setter.Value>
  14:                     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  15:                         <GradientStop Color="#FFAEBECE" Offset="0"/>
  16:                         <GradientStop Color="#FFD7E7F7" Offset="1"/>
  17:                     </LinearGradientBrush>
  18:                 </Setter.Value>
  19:             </Setter>
  20:         </Style>
  21:         <Style TargetType="{x:Type StackPanel}">
  22:             <Setter Property="Margin" Value="5"/>
  23:         </Style>
  24:         <ResourceDictionary.MergedDictionaries>
  25:             <ResourceDictionary Source="/RibbonControlsLibrary;component/Themes/Office2007Blue.xaml"/>
  26:         </ResourceDictionary.MergedDictionaries>
  27:     </ResourceDictionary>
  28: </ribbon:RibbonWindow.Resources>
  29:  
  30: ...[DELETED SECTIONS]...
  31:  
  32: <Border Grid.Column="0" Grid.Row="1" Style="{StaticResource StackPanelBorder}" >
  33:    <StackPanel Grid.Column="0" Grid.Row="1" x:Name="stackRecentClients" />
  34: </Border>

It was nice to see my screen look like it was supposed to.  Notice the left and right border look ok now.

implicitstyles2

The only thing I can conclude is that by using implicit styling, I was colliding with border elements that were emitted by the ribbon control.  Not something that might be immediately obvious, but something I will always keep in mind going forward.

  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Add to favorites
  • RSS
  • StumbleUpon
  • Twitter
  • Tumblr
  • email
  • LinkedIn
  • Netvibes
  • Posterous
  • Suggest to Techmeme via Twitter
  • Technorati

Leave a Comment

Previous post:

Next post: