Archive for the ‘Tutorial’ Category.

How To Animate a Changing Property in a Custom Control in Silverlight

For my recent visualization, I created a custom control in Silverlight that animated the color of a Path every time a “Fill” property on the control was changed. I thought I would pass along my learning from this process.

First thing I learned was that you cannot use TemplateBinding in a Storyboard (I think). I asked this question on Stack Overflow and I haven’t gotten an answer. But I’m pretty sure that in Silverlight you cannot use TemplateBinding to attach a property to a KeyFrame value. This means that you have to have a pointer in the control code the allows access to the KeyFrame so you can update the value.

I’ll walk through the conceptual part of animating a property in a Custom Control in Sivlerlight and then walk through the code to it.

Step 1: Create a PART to your control to hold the Storyboard and a PART to hold the KeyFrame you want to manipulate

I cover how to make a PART to your control here because it was too much to put into a single blog post. You’re going to want to make your Storyboard a PART that is accessed via resources (via MyControlName.Resources[MyStoryboardName]) and your KeyFrame should be a PART that is accessed the normal way (via the GetTemplateChild(MyKeyFrameName) method).

Step 2: Create the DependencyProperty you want to drive the animation

Yet another chance for me to endlessly flog Robby Ingebretsen’s awesome Silverlight Code Snippets. If you use these, use ‘sldpc’, which is the DependencyProperty with a property changed callback. We want to manually fire the animation when the property changes, so we’re going to do that in the callback.

If you don’t want to use Robby’s stuff, here’s the code for a DependencyProperty with a property changed callback. Because my visualization animates the color, I called my property “Fill”.

public SolidColorBrush Fill
{
    get { return (SolidColorBrush)GetValue(FillProperty); }
    set { SetValue(FillProperty, value); }
}

public static readonly DependencyProperty FillProperty =
    DependencyProperty.Register("Fill", typeof(SolidColorBrush), typeof(County),
    new PropertyMetadata(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), new PropertyChangedCallback(OnFillChanged)));

Step 3: Hook up a property changed callback and run the animation

Then, all you need to do is go into the property changed callback that you have created and assign your the new valie of the property to the keyframe value of the animation you want to run. Then run the animation.

private static void OnFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    MyControlType thisControl = d as MyControlType;
    if ((thisControl != null) && (thisControl._myStoryboard != null))
    {
        SolidColorBrush newBrushHolder = (SolidColorBrush)e.NewValue;

        thisCounty._myKeyFrame.Value = newBrushHolder.Color;
        thisCounty._myStoryboard.Begin();
    }
}

And now every time you change that value in the control, it will animate to the new value. Simple as that.

Create A Snapping Slider In Blend Using Behaviors (Silverlight 3 or WPF)

UPDATE: It turns out that in WPF, there is an easier way to snap the slider. For integers, simply check the “IsSnapToTickEnabled” and set your TickFrequency accordingly. Which means that this behavior is really only useful for Silverlight, which doesn’t have those properties.

Behaviors are easily the coolest thing that has ever happened to anything.

Perhaps I overstate my case somewhat. But they’re still pretty cool.

To me, a wonderful example is the ability to let designers/developers get some really cool functionality out of the Silverlight or WPF slider.

Now, one might normally think that there is a simple way to make your slider values to snap to an integer or to some incremental number (perhaps base 2 or base 10). Alas, one would be wrong. There have been a couple solutions to this problem (see here and here), but they usually involve creating a new slider subclass with the additional functionality if you really want the interaction to be reusable.

However, behaviors makes all this unnecessary. What is even better is that there is no code difference between WPF and Silverlight on this one. That’s right… this tutorial and the code that goes with it works exactly the same in Silverlight as it does in WPF.

SnappingSlider Behavior (SnappingSlider.cs) – Works for Silverlight and WPF

WPF SnappingSlider Behavior (All Project Files)

Silverlight SnappingSlider Behavior (All Project Files)

You can also download the behavior here (just the cs file) which would make me happy because it ups my street cred among the Silverlight homies (says the whitest man on earth).

If you want to learn how to create it yourself, let’s get started.

In your project in Blend, right-click on the project and go to “Add New Item…”

clip_image001[4]

Choose “Behavior” from the list and type in the name of the behavior you want to create

clip_image001[6]

This is where Blend is way cooler than Visual Studio… it gives you pretty much all the code and imports all the appropriate references for creating a behavior. So, first change the behavior associated object type to a Slider:

public class SnappingSlider : Behavior<Slider>

And go into the inside the OnAttached method, enter the following code:

AssociatedObject.ValueChanged +=new System.Windows.RoutedPropertyChangedEventHandler<double>(AssociatedObject_ValueChanged);

Hint to Code Newbies: If you get to the “+=” part and hit the Tab key twice it will add the necessary code.

Inside the AssociatedObject_ValueChanged method, I added the following code:

private voidAssociatedObject_ValueChanged(objectsender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
{
  
//Let the slider be equal to the Maximum and Minimum values
  
if((e.NewValue != AssociatedObject.Maximum) && (e.NewValue != AssociatedObject.Minimum))
    {
      
//Using the Minimum value as a starting point, only allow values that are
        //   a multiple of the SmallChange value. If you want to simply round to
        //   integers, set it so that:
        //   SmallChange = 1
      
doublecalcValue = Math.Floor((e.NewValue – AssociatedObject.Minimum) / AssociatedObject.SmallChange);
        calcValue = (calcValue * AssociatedObject.SmallChange) + AssociatedObject.Minimum;
        AssociatedObject.Value = Math.Round(calcValue);
    }
   
else
   
{
       
//Sometimes it hiccups on me, so I used this to catch those
       
AssociatedObject.Value = Math.Round(e.NewValue);
    }
}

Once you have that code in place, build the project (menu option Project –> Build Project).

Now you should have the behavior available in the “Assets” tab under “Behaviors” (at the bottom of the picture below).

clip_image001[8]

 

Just drag it onto your Slider and set the Minimum, Maximum and SmallChange properties appropriately. Remember that SmallChange is the value is that is acting as your increment controller.

How To Create A ListBox with CheckBoxes (or RadioButtons) In Silverlight 3

To set the scene: You have a ListBox that is being populated by some collection and you want the user to scroll through the ListBox and either check a bunch of things or check one thing. Basically, you want a list of checkable items. If this is what you’re trying to do, this is the tutorial that lets you do it without any code… simply by applying a style to your ListBox.

Download finished tutorial: ListBox With CheckBoxes (or RadioButtons) Project in Silverlight 3

Go here to see the final result.

First, you should know right off the bat that this tutorial is for Silverlight 3 only. It uses a data binding functionality called RelativeSource binding that isn’t available in earlier versions of Silverlight.

OK… to start out, right click on your ListBox and go to:

Edit Additional Templates –> Edit Generated Item Container (ItemContainerStyle) –> Edit a Copy…

clip_image001

Name your new template and Blend will generate the default ItemContainerStyle for the ListBox.

Split up the grid so that there is room for your CheckBox or RadioButton. I’m going to put mine on the left, set HorizonalAlignment and VerticalAlignment to “Center”, reset the Content property" and make the whole thing twice as big by setting the RenderTransform X and Y to 2.

clip_image001[5]

If you’re really picky about making sure that your CheckBox is centered appropriately, change the Width and Height to “16”.

OK… so we’ve got the CheckBox in there, but it doesn’t really do anything. So let’s set the binding so that it works. Sadly, Blend doesn’t have an obvious way (that I can see) of setting a RelativeSource binding, so just type this into your CheckBox (or RadioButton):

IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Mode=TwoWay}"

This binding will make it so that when the user selects or unselects an item, the CheckBox or RadioButton will reflect this decision. Similarly, when the user checks or unchecks the CheckBoxes or RadioButtons, the selection will reflect these actions.

Now, we just need to make sure our selection option on the ListBox reflects our interface choice. If you’re using CheckBoxes, make sure that your ListBox SelectionMode is set to “Multiple” or “Extended”.

clip_image001[1]

If you’re using RadioButtons, it needs to be set to “Single”.

And you’re done! You can now set any ListBox to hold a list of checkable items simply by assigning it this ItemContainerStyle.

CheckBoxRadioButtonExample

And you should have something that looks and acts like this.

How To Get a Silverlight 3 AutoCompleteBox To Show Sample Data in Blend 3

Download Project Files for AutoCompleteBox Sample Data Project

So you’re playing around with Silverlight in Blend 3 and you set up some sample data. (If you don’t know how to do that, I’ll get to that in this tutorial too.) Your sample data is all set up and you’ve attached it to your AutoComplete box… but nothing happens. You get angry and throw your computer out a window (unless it’s a MacBook, in which case you apologize to it for flirting with Microsoft technologies and take it for a little cuddle), but you eventually think you want to try again and so you go looking for the problem on the internet. Hopefully that is what brought you here.

I talk too much, I know.

Just to start out at the beginning, if you didn’t know that Silverlight 3 had an AutoCompleteBox, that’s because it isn’t a default control. You can install it and several other fantastic controls via the Silverlight Toolkit. If you don’t have this installed, do so now.

With the Silverlight Toolkit installed, let’s just make sure we have the right problem.

OK… lets create our sample data. In the top right corner of Blend, you’ll see a couple of tabs. Click on the “Data” tab and click on the “Add sample data” menu and choose “Define New Sample Data…”

clip_image001

Name your database something short (you’ll see why later) and rename the “Collection” collection to something less confusing, like “Sample”. Add some string properties and give them handy names. You can see my sample data as a starting point…

clip_image001[5]

That’ll do for now. Now, draw an AutoCompleteBox into your UserControl and drag the Sample collection on top of it. It will set itself to be the default ItemsSource. Now, hit F5 to run your application. It should act like this one below… if you type stuff, nothing comes up… but if you type “e”, you can see (in my sample, at least), it shows a set of items labeled, “Expression.Blend.SampleData.AutoData.SampleItem”.

clip_image001[1]

This is because the filter being used by default in the AutoCompleteBox takes the items and converts them directly to strings. If the item itself is an object (like this example and like most real data you’re probably using), it will convert it into the string representation of that data type.

So let’s fix it. First, we’re going to create an ItemTemplate for our AutoCompleteBox so that we can actually see the data in it. The quickest way to do this is actually kind of silly. Create a ListBox in your app and drag the data collection into it. It will auto-generate a super simple ItemTemplate. Then right-click on your AutoCompleteBox and go to “Edit Additional Templates –> Edit ItemTemplate –> Apply Resource –> [name of generated template here]”

clip_image001[7]

Delete your ListBox, just to clean things up.

Now you’ll have an AutoCompleteBox that shows the data like you want it, but it’s still looking at the “Expression.Blend.SampleData.SampleItem” when you type in the box, so it’s not acting the way we want. In order to do that, we just have to override the “ToString()” method in the AutoData. Open up “AutoData.xaml.cs”

clip_image001[1]

Scroll down to the “SampleItem” class and make the beginning of that class look like this:

public class SampleItem : System.ComponentModel.INotifyPropertyChanged
{
    public override string ToString()
    {
        return Name;
    }

If you want to use another property as your text return, just use that property name instead of Name. If you want to use a combination of properties, you could do something like this:

return Name + " - " + CompanyName;

Although, if you want it to look at two fields, you should change the FilterMode to “Contains”

clip_image001[3]

And… tada! You’re done… unless you want to give it some styling to better enhance the user experience (like putting the name at the top so that it draws the eye).

clip_image001[3]

Also valuable, check out Tim Heuer’s post on turning the AutoCompleteBox into an editable ComboBox.

Flex Anchored Layout in Silverlight

When I started using Silverlight, I was moving over from Flex, and the first thing I noticed was: Where is my anchored positioning?

In some cases using a table (Grid) for a layout is not ideal, and if your moving over from Flex like I did, you may want to have something you’re familiar with. This post walks though how to simulate anchored layout in Sliverlight, using a single cell and applying alignment and margin properties to its elements.

The following example, built in Silverlight, illustrates the types of anchored positioning:

Example screen normal size

Example screen normal size

Example screen stretched

Example screen stretched

Here is the XAML for the layout of the screen above.

XAML for screen

XAML for screen

One Cell, Many Possibilities

As you can see from the screenshots above, as the page is stretched, the elements stretch and retain their positions also. Normally this type of layout in Silverlight would require a Grid with 3 columns and 3 rows, and you would have to add the definitions for them as well as set the column and row properties for each element inside the Grid. To simplify how the page is layed out, only a single cell is needed, and instead the HorizonalAlignment, VerticalAlignment, and Margins are adjusted. A nice side effect of this type of layout, is the XAML used is significantly reduced. I’ll go through each element in turn and explain how it’s layout is simulated from Flex. On the left side of each explanation is the constraints as would be defined in Flex.

Header

Flex layout constraints for Header

Flex layout constraints for Header

     

The header of the page stays at the top and stretches left and right. In Flex a top, left, and right position for the Header would have been set. In Silverlight, the header of the page is anchored to the top using a VerticalAlignment of Top, and then stretches both left and right by using a HorizontalAlignment of Stretch. A fixed Height is set, and a left Margin of 100 is applied.


<Border Background=”Red” Height=”50″ VerticalAlignment=”Top” HorizontalAlignment=”Stretch” Margin=”100,0,0,0″>
<TextBlock Text=”Header” Style=”{StaticResource Number}” />
</Border>

Navigation

Flex layout constraints for Navigation

Flex layout constraints for Navigation

     

The navigation pane on the page stays vertically centered on the left. In Flex, the verticalCenter and left positions would be set for the Navigation. In Silverlight, VerticalAlignment is set to Stretch, and HorizontalAlignment is set to Left, with a fixed Height applied to the element.



<Border Background=”Green” Width=”80″ Height=”200″ VerticalAlignment=”Stretch” HorizontalAlignment=”Left”>
<TextBlock Text=”Navigation” Style=”{StaticResource Number}” />
</Border>

Body

Body layout constraints in Flex

Body layout constraints in Flex

     

The body of the page stretches in all directions while still leaving room for the other elements. In Flex, top, left, right, and bottom positions would be set. In Silverlight, a VerticalAlignment and HorizontalAlignment of Stretch is set, as well as Margins on all sides.



<Border Background=”Orange” VerticalAlignment=”Stretch” HorizontalAlignment=”Stretch” Margin=”100,80,80,80″>
<TextBlock Text=”Body” Style=”{StaticResource Number}” />
</Border>

Buttons

Flex layout constraints for Buttons

Flex layout constraints for Buttons

     

The buttons on the page are centered horizontally on the bottom. In Flex, the positions of bottom and right would be set. In Silverlight, VerticalAlignment is set to Bottom, and HorizonalAlignment is set to Center with a fixed Width and Height on the element.



<Border Background=”Blue” Width=”200″ Height=”60″ VerticalAlignment=”Bottom” HorizontalAlignment=”Stretch”>
<TextBlock Text=”Buttons” Style=”{StaticResource Number}” />
</Border>

Page

Flex layout constraints for Page

Flex layout constraints for Page

     

The page number is in the bottom right of the page. In Flex, a position on the bottom and right would be set. In Silverlight, VerticalAlignment is set to Bottom, and HorizontalAlignment is set to Right, with a fixed Width and Height applied to the element.



<Border Background=”Purple” Width=”80″ Height=”60″ VerticalAlignment=”Bottom” HorizontalAlignment=”Right”>
<TextBlock Text=”Page” Style=”{StaticResource Number}” />
</Border>

Summary

The use of the Grid layout can be simplified and simulate Flex anchored layout by only using a single cell, and applying alignments with margins. Standard absolution positioning can also be achieved within a single cell grid by applying a VerticalAlignment of Top, a HorizontalAlignment of Left, and then using left and top margins for x and y respectively. The translation from Flex anchored layout to Silverlight can be summarized by the table below:

 Description 

 Flex 

 Silverlight 

Top left position top, left VerticalAlignment=Top, HorizontalAlignment=Left
Bottom right position bottom, right VerticalAlignment=Bottom, HorizontalAlignment=Right
Center horizontally center HorizontalAlignment=Center
Center vertically verticalCenter VerticalAlignment=Center
Stretch horizontally left, right HorizontalAlignment=Stretch
Stretch vertically top, bottom VerticalAlignment=Stretch

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

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.

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

Update: Project files for the Silverlight Mac ScrollViewer have been uploaded.

 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.

Styling the ScrollViewer

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?

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.