Control Styling Tips: ScrollBar

Hello!
In this article, I’d like to provide you with some information and tips that you’ll find useful when styling a Silverlight 3 ScrollBar.

Visual states.  CommonStates (Normal, MouseOver and Disabled) and the following template parts:

Used when the ScrollBar is oriented horizontally:

  • HorizontalLargeDecrease (RepeatButton)
  • HorizontalLargeIncrease (RepeatButton)
  • HorizontalRoot (FrameworkElement)
  • HorizontalSmallDecrease (RepeatButton)
  • HorizontalSmallIncrease (RepeatButton)
  • HorizontalThumb (Thumb)

Used when the ScrollBar is oriented vertically:

  • VerticalLargeDecrease (RepeatButton)
  • VerticalLargeIncrease (RepeatButton)
  • VerticalRoot (FrameworkElement)
  • VerticalSmallDecrease (RepeatButton)
  • VerticalSmallIncrease (RepeatButton)
  • VerticalThumb (Thumb)

Template binding. Try template binding Background, BorderBrush, Foreground, BorderThickness or Padding.

ScrollBar tips.

  • There are two sets of parts, named with Horizontal- and Vertical- prefixes, each set appropriate for the horizontal or vertical orientation of a ScrollBar, respectively.
     
  • The Root part (either Horizontal, Vertical or both) is mandatory and its purpose is to contain all the elements that make up the ScrollBar in a particular orientation. Create a Grid named HorizontalRoot (or VerticalRoot) that has five columns (or five rows) sized Auto, Auto, Auto, Star and Auto.
     
  • The space in which the thumb moves is called the track. The track is not a part and it is optional. Place the object(s) representing the track into the Root part, either spanning all five columns/rows or spanning just the middle three.
     
  • The Thumb part is mandatory. Make the object(s) representing the thumb into a Thumb control and name it HorizontalThumb (or VerticalThumb). Place the Thumb part in the middle column/row of the Root part and give it a Width and Height so that the column/row will size to fit it. Don’t put a margin on the Thumb because that will interfere with layout. You can get the same effect by putting a margin on the root object of the Thumb’s template.
     
  • So that the user can click on the track either side of the thumb to move it in large increments, place a RepeatButton in the two columns/rows either side of the Thumb part and name them VerticalLargeDecrease and VerticalLargeIncrease (or HorizontalLargeDecrease and HorizontalLargeIncrease). So that the RepeatButtons function but are not seen, give them zero Opacity. Alternatively, apply a template to the RepeatButtons that contains a single object with zero Opacity.
     
  • If you want the user to be able to click on a button at either end of the track to move the thumb in small increments then make the object(s) representing these buttons into RepeatButtons and name them VerticalSmallDecrease and VerticalSmallIncrease (or HorizontalSmallDecrease and HorizontalSmallIncrease). Place them in the two end columns/rows.

To make this into a control, a visual designer has comped out some ScrollBar states together with the MouseOver and Pressed states of the VerticalThumb, VerticalSmallDecrease and VerticalSmallIncrease parts:

mouseStates

The comp artwork is then imported into Blend 3. Here’s the XAML for the Normal state. Note, this XAML is not yet a styled ScrollBar, it is still just artwork consisting of Panels and Shapes:

<Grid x:Name="verticalscrollbar" Width="17" Height="146" >
      <Rectangle x:Name="track" Fill="#FF3D3D3D" StrokeThickness="0" />
      <Path x:Name="smalldecrease" Fill="Gray" Stretch="Fill" Width="7" Height="7" Data="M196.89876,311.82065 L204.06047,311.82065 L200.42426,304.87872 z" Margin="0,5,0,0" VerticalAlignment="Top"/>
      <Rectangle x:Name="thumb" Fill="Gray" RadiusX="3" RadiusY="3" Height="61" Width="7" Margin="0,24,0,0" VerticalAlignment="Top"/>
      <Path x:Name="smallincrease" Fill="Gray" Stretch="Fill" Width="7" Height="7" Data="M196.89876,304.83246 L200.52762,312.02783 L204.07646,304.83078 z" Margin="0,0,0,5" VerticalAlignment="Bottom" />
</Grid>

Practice making the artwork into a ScrollBar with the following steps.

  • Paste the XAML into a new Silverlight 3 Application project.
     
  • Select verticalscrollbar and click Tools > Make Into Control > ScrollBar > OK. In this step, Blend removed verticalscrollbar (and everything inside it) and put a new ScrollBar in its place. Next, it turned verticalscrollbar into the template of a new ScrollBar style and applied that new style to the new ScrollBar.
     
  • Let’s make the root of the template, which is currently called verticalscrollbar, into the VerticalRoot part. Select verticalscrollbar and click Tools > Make Into Part of ScrollBar > VerticalRoot. verticalscrollbar has been renamed to VerticalRoot.
     
  • Click the blue ruler to the left of VerticalRoot to add new row dividers as shown:

image

  • By drawing the row dividers as shown, the parts will be in the correct rows. track has a RowSpan of 5, smalldecrease is in Row 0, thumb is in Row 2, and smallincrease is in Row 4.
     
  • The VerticalSmallDecrease part is not in the template yet. We do have the artwork for this part though: it’s the object named smalldecrease. So we can use the Make Into Part command (which is a variation of the Make Into Control command) to make smalldecrease into the VerticalSmallDecrease part, which is of type RepeatButton. Select smalldecrease and click Tools > Make Into Part of ScrollBar > VerticalSmallDecrease > OK. This takes us into the small decrease RepeatButton’s template.
     
  • We don’t need [ContentPresenter] , so delete it.
     
  • Select smalldecrease and set Width and Height to 7.
     
  • Select [Grid] and set Width and Height to 17 and Background to Solid color brush > Transparent. You’ll notice a slight layout anomaly that we should correct now.
     
  • Return scope to ScrollBarStyle1 (ScrollBar template) .
     
  • Select VerticalSmallDecrease and reset Width, Height and Margin.
     
  • Navigate back into RepeatButtonStyle1 (RepeatButton template) .
     
  • Now to make the states look like those in the visual designer’s comp. Ensure the States panel is open and select the MouseOver state. Set smalldecrease’s Fill to #FFCCCCCC.
     
  • Select the Pressed state and set smalldecrease’s Fill to #FFE5E5E5.
     
  • Click the ‘Add transition’ button on the Normal state and click Normal -> MouseOver. Set the transition’s duration to 0.2 seconds.
     
  • Return scope to ScrollBarStyle1 (ScrollBar template) .
     
  • Now repeat the steps above for smallincrease.
     
  • Select thumb and click Tools > Make Into Part of ScrollBar > VerticalThumb > OK. The Thumb object that Blend created in this step has no minimum height so we should correct that now.
     
  • Return scope to ScrollBarStyle1 (ScrollBar template) .
     
  • Select VerticalThumb. Set Margin to Left:5, Right:5, Top:0, Bottom:0. Reset Height and set MinHeight to 7.
     
  • Navigate back into ThumbButtonStyle1 (Thumb template) .
     
  • Select the MouseOver state and set thumb’s Fill to #FFCCCCCC.
     
  • Select the Pressed state and set thumb’s Fill to #FFE5E5E5.
     
  • Set the Normal -> MouseOver transition’s duration to 0.2 seconds.
     
  • Return scope to ScrollBarStyle1 (ScrollBar template) .
     
  • Select VerticalRoot and, in the Parts panel, double-click VerticalLargeDecrease to create that part as a child of VerticalRoot. Set VerticalLargeDecrease’s Row to 1 and its Opacity to 0.
     
  • Select VerticalRoot and, in the Parts panel, double-click VerticalLargeIncrease. Set VerticalLargeIncrease’s Row to 3 and its Opacity to 0.
     
  • Set the Heights of the five rows of VerticalRoot to Auto sized, Auto sized, Auto sized, Star sized and Auto sized and reset their MinHeights so that VerticalRoot looks like this:

image

  • Select the Disabled state. Select VerticalRoot and set its Opacity to 50.
     
  • Build and run your application and test your ScrollBar.

You should now have a working ScrollBar!

- Steve

Comments

  • Anonymous
    May 07, 2010
    Why isn't something like this possible in WPF application instead of Silverligth ? Kind Regards, Mike