31 Days of Windows Phone | Day #21: Silverlight Toolkit for Windows Phone

This post is Day #21 in a series called the 31 Days of Windows Phone.

After talking about the Map Control yesterday, it occurred to me that you might not be aware that there are TONS of controls available to you through the Silverlight Toolkit.  Today’s article addresses the Silverlight Toolkit for Windows Phone, specifically, but also check out the Silverlight 3 Toolkit as well.

What is a Toolkit?

The original toolkit for Silverlight 3 was a huge pile of extra controls that you could use in your projects.  The controls ranged from charting to accordions, date pickers to autocomplete boxes.  What’s awesome about this toolkit is that it’s completely compatible with our Windows Phone applications that use Silverlight.

The Silverlight Toolkit for Windows Phone 7 is a similar idea, but it only includes additional controls that would be used in a Windows Phone application.  It includes:

  • ContextMenu
  • DatePicker & TimePicker
  • GestureListener
  • ToggleSwitch
  • WrapPanel

I’m going to spend the rest of this article showing examples of each of the controls in this Toolkit, but I also highly encourage you to peruse the Silverlight 3 Toolkit as well.  There’s tons of controls, examples, and code that you can use in your projects.  I’m to cover the charting controls from that toolkit later in this series, but for those of you that are impatient, you can check it out on your own now.

ContextMenu Control

If you’ve had an opportunity to pin something to the Start page, you’ve seen the ContextMenu in action. Here’s what it looks like when I try to pin Internet Explorer to my Start menu in the emulator (tap and hold to show this menu):

contextmenucontrol

In order to make this menu appear, we need the ContextMenu control from the Silverlight Toolkit.  As with all of the examples in this article, we need to add the Silverlight Toolkit assembly to our project.  You can see it here:

addreference

Once we’ve added it, we’ll also need to add that namespace to the context of our XAML page.  To add this namespace, add this to the <phone:PhoneApplicationPage> tag at the top of your file:

xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

Now we can get down to business.  Let’s take a common control that we might want to offer our users more options for, the Rectangle.  Perhaps we have a shape, image, icon, etc. that our users need to interact with.  Perhaps there is more than one thing you want to do with this Rectangle (think “right-click” menu).  By adding a ContextMenu to our Rectangle, we can pop a menu any time that our user taps and holds on that object.  This can be ANY XAML element, so you could even apply this to the background of your application, portions of a Panorama, or even Buttons.  Here’s how it’s applied in XAML:

<Rectangle Width="100" Height="100" Fill="Red">
	<toolkit:ContextMenuService.ContextMenu>
		<toolkit:ContextMenu>
			<toolkit:MenuItem Header="this is menu item 1" Click="MenuItem_Click" />
			<toolkit:MenuItem Header="this is menu item 2" Click="MenuItem_Click" />
			<toolkit:MenuItem Header="this is menu item 3" Click="MenuItem_Click" />
		</toolkit:ContextMenu>
	</toolkit:ContextMenuService.ContextMenu>
</Rectangle>

We basically tie in to the ContextMenuService, adding a ContextMenu to our specific control.  You can see that each item can also have a Click event, allowing us to tie these menu options back to our code.  Here’s a screenshot of my ContextMenu:

contextmenu

If you test this in your emulator, you might also notice that everything in the background zooms out a little, as if it’s dropping into the background, bringing the menu to the front and center of the user’s attention.  You might not want this behavior, so the <toolkit:ContextMenu> item has an additional attribute which is IsZoomEnabled.  Setting this to false will stop that zooming animation from happening automatically.

It’s that simple to add the equivalent of a right-click menu to our XAML elements.  This one will likely be the most used of the 6 controls (unless the GestureService  takes off).

DatePicker and TimePicker Controls

As I was preparing the code for this article, these two presented an interesting challenge for me.  They are SO straightforward simple that I just couldn’t figure out what I was doing wrong.  As it turns out, there’s a little magic involved.  I’ll explain that in a bit.  First, let’s talk about getting these controls on our page.  That’s the easy part:

<toolkit:DatePicker Value="7/22/1976" />
<toolkit:TimePicker Value="12:02 AM" />

When you add these controls to your page, they work as advertised.  They allow the user to select a date (starting with the initial date you provide…if you don’t provide one, it uses “today’s” date.)  Here’s screenshots of each:

datepicker   timepicker

OK, now to talk about the perplexing problems these controls presented me.  You’ll notice in the screenshots above, there’s an ApplicationBar.  And it has two icons (with no images).  After beating my head on my desk for a few minutes, I realized that these are the Done and Cancel buttons.  (You can also discover this by clicking on the ellipsis (…) icon.  They’ll slide up to reveal their text labels.

To make these icons actually work, you need to follow these instructions exactly:

  1. Create a folder in the root of your project named “Toolkit.Content”
  2. Add two images to that folder with the specific names:
    1. ApplicationBar.Cancel.png (download it here)
    2. ApplicationBar.Check.png (download it here)
  3. Make sure that the Build Action on those two images is set to “Content.”  If you haven’t done this before, just click on the images, and change it in the Properties tab.

properties

Once you’ve followed those specific instructions, IT JUST WORKS!  I wish this all just happened automatically, but at least we know.  And knowing is half the battle, right?

Here’s a look at the “working” ones:

datepickerfinal   timepickerfinal

GestureListener Control

Up until this point in the 31 Days of Windows Phone, you may have been wondering when you were going to find out how to handle gestures from your user in your application.  Today’s the day!  (DISCLAIMER: this is “one” way to do this.  There are plenty of other approaches to gesture handling, but this is definitely the easiest, and if you’ve been reading along, that’s what this series is optimized for.  The easiest way to accomplish something in Windows Phone.  Not necessarily the best practices that you should ALWAYS use.)

OK, now that that’s cleared up, let’s talk abut the GestureListener.  Much like the ContextMenu, we’re going to let the GestureService know that we’ve created a GestureListener, and then we basically rig up event handlers for the specific gestures we’re looking for.  Remember that we apply this to a specific XAML element, so the gestures will only be recognized on the control that this is applied to.  The gestures that are supported in the GestureListener are:

  • Tap
  • DoubleTap 
  • Hold
  • Flick
  • Pinch
  • Drag and Drop

Each of these are implemented in such a way, however, that it’s almost TOO easy to accomplish.  Pinch and Drag have a few more technical details (basically the delta between when the gesture started and when it completed.)  Here’s what our XAML would look like (on another rectangle):

<Rectangle Width="100" Height="100" Fill="Blue">
	<toolkit:GestureService.GestureListener>
		<toolkit:GestureListener 
			DoubleTap="DoubleTapped"
			Tap="Tapped"
			Hold="Held"
			DragStarted="DragStart"
				DragDelta="DragDelta"
				DragCompleted="DragEnd"
			Flick="Flicked"
			PinchStarted="PinchStart"
				PinchDelta="PinchDelta"
				PinchCompleted="PinchEnd" />
	</toolkit:GestureService.GestureListener>
</Rectangle>

As you can see, I can just define the gestures I want to recognize, and then assign event handlers to them, allowing me to translate that gesture to code very simply.  In the sample code for the Silverlight Toolkit for Windows Phone, there’s a great example of how to handle each of these events.

ToggleSwitch Control

You may have seen this control if you’ve tried to change the Date/Time in the Emulator.  Here’s a quick example:

dateandtime

Adding this to the page is simple:

<toolkit:ToggleSwitch Header="Receive updates automatically"/>

In the above screenshot, where it says “24-hour clock”, my example would read “Receive updates automatically.”  The On/Off text is automatically handled for you, thankfully.  If you’d like to do a little more customization to this control, however, it’s pretty easy to do.  There’s a HeaderTemplate and a ContentTemplate that we can leverage to make this control more “our own.”  There’s also Checked and Unchecked events that fire when the switch is manipulated.  (Think of this control much like you would a CheckBox).  Here’s an example of these being used (and bound to a data source):

<toolkit:ToggleSwitch Header="12:02 AM">
    <toolkit:ToggleSwitch.HeaderTemplate>
        <DataTemplate>
            <ContentControl FontSize="{StaticResource PhoneFontSizeLarge}" Foreground="{StaticResource PhoneForegroundBrush}" Content="{Binding}"/>
        </DataTemplate>
    </toolkit:ToggleSwitch.HeaderTemplate>
    <toolkit:ToggleSwitch.ContentTemplate>
        <DataTemplate>
            <StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Alert: " FontSize="{StaticResource PhoneFontSizeSmall}"/>
                    <ContentControl HorizontalAlignment="Left" FontSize="{StaticResource PhoneFontSizeSmall}" Content="{Binding}"/>
                </StackPanel>
                <TextBlock Text="every weekday" FontSize="{StaticResource PhoneFontSizeSmall}" Foreground="{StaticResource PhoneSubtleBrush}"/>
            </StackPanel>
        </DataTemplate>
    </toolkit:ToggleSwitch.ContentTemplate>
</toolkit:ToggleSwitch>

Finally, we have the WrapPanel. While its purpose might seem obvious, it’s a control that is glaringly missing from the standard set of controls available in the original set.

WrapPanel Control

A WrapPanel is basically a StackPanel with some extra awesome sauce added.  I was building a game a few months ago, and I wanted to create a screen that had 30 buttons on it.  Since this was before the WrapPanel was available, I had to dynamically create a Grid, and then assign each new button to a Grid location.  Much more work than I wanted to do, just to get 30 buttons in a nice 5×6 layout.  The WrapPanel solves that problem for us.

In the example below, I have created a WrapPanel that contains 12 buttons. 

<toolkit:WrapPanel>
	<Button Width="75" Height="75" Content="1" />
	<Button Width="75" Height="75" Content="2" />
	<Button Width="75" Height="75" Content="3" />
	<Button Width="75" Height="75" Content="4" />
	<Button Width="75" Height="75" Content="5" />
	<Button Width="75" Height="75" Content="6" />
	<Button Width="75" Height="75" Content="7" />
	<Button Width="75" Height="75" Content="8" />
	<Button Width="75" Height="75" Content="9" />
	<Button Width="75" Height="75" Content="10" />
	<Button Width="75" Height="75" Content="11" />
	<Button Width="75" Height="75" Content="12" />
</toolkit:WrapPanel>

In the screenshot below, you’ll see that the WrapPanel dynamically decides how they will fit on each row, and stacks the next row below the first.  No overlap (much like a StackPanel), but also the freedom to not worry about the size of your content screwing up your layout.  Here’s a screenshot:

wrappanel

In my code example, below, you’ll see that I’ve rigged up events on Button #1 and Button #2.  They make the size of all of the buttons grow and shrink.  Playing with this example should demonstrate exactly how the WrapPanel dynamically moves your content around, even at runtime.  Here’s a screenshot of the same code, but with the buttons enlarged significantly:

wrappanelfinal

So that’s it!  We covered all 5 of the new controls available in the Silverlight Toolkit for Windows Phone.  Make sure you download it today, because I think you’ll find yourself needing these sooner than later.

Download the Code

In this sample code, you’ll find a simple example of each of the controls in the Silverlight Toolkit for Windows Phone.  On Day #31, we’ll be covering the Silverlight 3 Toolkit, and how we can leverage the charting controls in our WP7 applications.

download

7 thoughts on “31 Days of Windows Phone | Day #21: Silverlight Toolkit for Windows Phone

  1. I enjoyed your presentations in Chicago and I'm enjoying your blog posts on all things WP7. Thank you very much!

  2. How I can change foreground colour?
    I tried:
    <toolkit:ContextMenu Name="ContextMenu" Opacity="0.7" Background="Black" Foreground="White">
    but it doesn't work.

  3. Thanks for the talk in Detroit, and these blog posts, I really enjoy and am learning from them.

    One thing I did notice, while testing my application with the various Color Themes. The Application Bar icons for the Date Chooser do not work well in the "light" theme. Should I have reverse colour icons and where do I install them?

    David

  4. Men are conservatives when they are least vigorous, or when they are most luxurious. They are conservatives after dinner.

  5. True knowledge exists in knowing that you know nothing. And in knowing that you know nothing, that makes you the smartest of all.

  6. Pingback: 31 Days of Mango | Day #9: Calendar API « Blankenblog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s