MSDN SpotlightAzure ShowcaseRIA Development CenterPHP for Windows ShowcaseTechNet Spotlight

Using Visual Studio 2010 to Write Killer WPF Apps for Windows 7

When you're running on the latest OS, building on the latest framework, and working in the latest version of Visual Studio, you can take advantage of a number of exciting new features. Learn how you can use Visual Studio 2010, WPF 4 and the Windows API Code Pack to plug your applications into the Windows 7 UI. 


Some of the most exciting elements of the Windows 7 UI, like the new taskbar, or jump lists, lie visually outside the application proper but are an important part of the application experience. As a WPF developer, you can tie into these elements to tailor your application for Windows 7, fully customizing its behavior both inside and outside the main window.

With WPF 4, you've got almost all you need to access the sharpest features of the Windows 7 UI. WPF 4 includes built-in support for the Windows 7 taskbar, including custom thumbnail previews, visual feedback from the taskbar with progress bars and icon overlays, and custom jump lists. These features are ultimately supplied by the Windows 7 native API, but WPF wraps these APIs with managed code and exposes them as WPF classes. That means you can create jump lists and other UI objects in XAML, and bind them through a number of dependency properties.

Visual Studio 2010 boasts a number of new WPF-related features of its own, including a new visual designer, drag-and-drop databinding, and intellisense for markup extensions in XAML. These features, combined with WPF's new taskbar classes, allow you to build state-of-the-art Windows 7 applications using the full power of the latest version of Visual Studio.

Although WPF 4 fully supports the taskbar, there are other aspects of the Windows 7 API that aren't covered. These include, for example, Windows 7-style common dialogs. You can get to these from WPF using the Windows API Code Pack, an external library of managed wrappers. The Windows API Code Pack also has its own set of shell and taskbar classes which can be used from WPF 3.5 SP1.

Databinding and the Visual Studio 2010 WPF Designer
Before we get too far into the Windows 7 specifics, lets take a look at putting together a basic data-driven WPF application in the new Visual Studio 2010 WPF designer. In Visual Studio 2010, you can set up data binding at design time by dragging data sources into the visual designer.

If you drag a data source item onto an existing control (say, a text field into a text box) the designer will create a window resource for that data source and then bind the field to the control. If, instead, you drag a data source item onto a container, the designer creates an appropriate bound control and adds that control to the container. You can set the control type if the default is not appropriate. In Screen 1, I've dropped a view from the AdventureWorks 2008 sample database into the window, automatically creating a data grid. We'll use the data grid when we explore displaying progress on the Windows 7 taskbar.


Screen 1: Dropping a view data source onto the main window generates a bound data grid.

As one additional item of basic setup, we'll set a window background using a gradient brush. Visual Studio 2010 builds in a visual brush editor that makes it easy to create and use gradient and image brushes as well as solid colors. Hitting the dropdown in the properties editor on a brush property brings up the editor, which allows you to visually set up gradients or select an image for an image brush.


Screen 2: Creating a background brush using the visual brush editor.

Working with the Windows 7 Taskbar
In Windows 7, you can show the progress of long operations on the taskbar as a progress bar that moves across the background of the task item. Internet Explorer, as an example, uses taskbar progress to track file downloads.

You work with the Windows 7 taskbar through the TaskbarItemInfo class, exposed as a dependency property on the main window. You can create the TaskbarItemInfo in XAML:


<Window.TaskbarItemInfo>
<TaskbarItemInfo
x:Name="TaskbarItemInfo1"
Description="Customer Browser: Using WPF 4 on Windows 7”
>
</TaskbarItemInfo>
</Window.TaskbarItemInfo>

And you can edit TaskbarItemInfo properties either directly in XAML or through the Visual Studio properties editor. The XAML snippet shows just the name and the Description property, which specifies the tooltip text for the taskbar. Most taskbar features are accessible through properties on this class.

To show the progress bar, you just need to set two of these properties, ProgressValue and ProgressState. ProgressState starts out at None; you can set it to Indeterminate to show a marquee-style progress bar, or set it to Normal, as we'll do here, to kick off a standard progress bar:


TaskBarItemInfo1.ProgressValue = 0;
TaskBarItemInfo1.ProgressState = TaskbarItemProgressState.Normal;

A ProgressValue of 1.0 shows a full progress bar. To track the filling of the data table, we'll first run a count query to count the total rows in the view, and use that as our full progress value. Then, we can hook up the data table RowChanged event and add the following two lines to update progress on the taskbar:


this.rowsUpdated++;
TaskbarItemInfo1.ProgressValue =
((double)this.rowsUpdated)/this.rowCount;

In addition to progress bars, you can use icon overlays to give feedback about the state of your application. An icon overlay is a small image that appears on top of the main application icon in the taskbar. Icon overlays can be used to communicate status appropriate for the application, such as playing or paused, online or offline. We'll use an icon overlay to show a filter setting for our customer list.

Screen 3 shows the sample application with the icon overlay on the taskbar. You can view customers by country in the main application by selecting a country in the combo box. If the filter is set, the taskbar icon is shown with a small image of the selected country's flag as an icon overlay.


Screen 3: Customer Browser application with filter setting shown as an icon overlay.

You set an overlay by assigning an image source to the TaskbarItemInfo's Overlay property. For the sample, I created a bitmap resource for each flag image. Then, when the filter is set, we can load the image from the window resources and set the overlay:

string resourceKey = “flag_” + countryName;
TaskbarItemInfo1.Overlay =
(ImageSource)this.TryFindResource(resourceKey);


Custom Thumbnails
Application thumbnail preview is one of the UI perks you'll get for free when your application runs on Windows 7. Windows 7 shows a thumbnail image of the main application window as a popup from the taskbar. Users can use the thumbnail preview to activate or close the application, or to choose between application instances.

You can easily customize your application's thumbnail image using the ThumbnailClipMargin property of the TaskbarItemInfo. With this property, you can specify a rectangle within the main window to use for a thumbnail, rather than showing the entire main window.

ThumbnailClipMargin is a dependency property, so in addition to specifying a static margin, you can bind it to the margin of another control to use that control as the application preview. I set the thumbnail preview to just show the customer data grid using this method. Rather than another snippet, let's take a look at this in Visual Studio:


Screen 4. Setting the ThumbnailClipMargin binding.

Screen 4 shows setting the binding in XAML, and it also shows Visual Studio's new markup extension intellisense. We need to set the binding Path to “Margin”, and we can pick Path out of the list of options.

The thumbnail preview can also include a set of toolbar buttons, letting the user send application commands directly from the preview. These might be used, for example, to send media commands such as play or pause. For the sample, I created a “Copy” toolbar button to copy the customer's email address from a textbox.

The TaskbarItemInfo class includes a collection property called ThumbButonInfos through which you can set up a thumbnail toolbar. Again, this is fully supported by Visual Studio 2010, and you can edit each thumb button item in the collection editor or work directly in XAML.

The XAML for a ThumbButtonInfo typically specifies the command to send, the command target, the image to use for the button, and the tool tip text. For our copy button, it looks like this:

<ThumbButtonInfo Command="ApplicationCommands.Copy"
Description="Copy E-Mail Address"
ImageSource="/wpf4example;component/Images/copy.png"
CommandTarget="{Binding ElementName=textBox1}" />

The button is automatically enabled or disabled according to whether text is selected in the text box through the magic of WPF commands.


Screen 5. Custom thumbnail image (showing just the datagrid) and the Copy toolbar button.

Jump Lists
Jump lists are lists of common tasks or files associated with an application that pop up in response to a right click on the taskbar, or pop out from start menu application items. You can customize your application's jump list by adding files, tasks, or your own task categories.

Jump lists are associated with an application itself, not a specific running instance. You can add a custom jump list to your application in procedural code, or by attaching a jump list to the application object in XAML (in app.xaml):

<JumpList.JumpList>
<JumpList ShowRecentCategory="True”
ShowFrequentCategory="True">
<JumpTask Title="Notepad”
Description="Run Notepad"
ApplicationPath="c:\windows\notepad.exe"
IconResourcePath="c:\windows\notepad.exe"/>
</JumpList>
</JumpList.JumpList>


When you set up a jump list in XAML, it's automatically applied to the Windows shell after the application is initialized.

Jump lists can contain jump tasks, as in the XAML snippet, which launch other programs, or they can contain jump paths, which link to files. Jump paths will only show up on your jump list if your application is a registered handler for the file type.

The Windows shell maintains a list of recent and frequent files selected by each application. You can display these lists in the application jump list by setting ShowRecentCategory and ShowFrequentCategory.

In addition to these standard categories, you can create custom categories. The code below adds a jump task link to calc.exe and puts it in a custom category.

JumpTask jumpTask1 = new JumpTask();
jumpTask1.ApplicationPath =
"C:\\windows\\system32\\calc.exe";
jumpTask1.IconResourcePath =
"C:\\windows\\system32\\calc.exe";
jumpTask1.Title = "Calculator";
jumpTask1.CustomCategory = "Calculation";
JumpList jumpList1 = JumpList.GetJumpList(App.Current);
jumpList1.JumpItems.Add(jumpTask1);
jumpList1.Apply();



Screen 6. A jump list with standard categories and a custom category.

Windows 7 Dialogs and Controls
One part of Windows 7 not covered by WPF 4 is the common file dialog API. For that, you can turn to the Windows API Code Pack. The code pack lets you launch common dialogs from your WPF application that know about Windows 7 shell features such as known folders and libraries.

To use the code pack, build the code pack solution and add references from the code pack assemblies to your application. At that point, you can use classes in the code pack name space, including CommonDialog.

Windows 7 has a list of known folders, such as Desktop, and Pictures Library, that you can specify instead of a file path with CommonDialog. This code starts the file open dialog in the pictures library.

CommonOpenFileDialog dlg = new CommonOpenFileDialog();
dlg.InitialDirectoryShellContainer =
(ShellContainer)KnownFolders.PicturesLibrary;

You can use known folders, or, more generally, shell objects, to specify a number of settings for the common open file and save file dialogs. For example, this line adds the video library as a new open location for the open dialog:

dlg.AddPlace((ShellContainer)KnownFolders.VideosLibrary,
FileDialog.AddPlaceLocation.Bottom);



Screen 7: A Windows 7 open file dialog with a custom open location.
The Windows API Code Pack also provides a WPF-wrapped explorer browser control, which you can use to display files and other shell objects within a Windows 7-style explorer interface. All it takes to use the control is to declare it in XAML:

<WindowsAPICodePackPresentation:ExplorerBrowser
x:Name=”explorerBrowser1”/>


And then to call Navigate on the underlying control to show the selected folder in your window:

explorerBrowser1.ExplorerBrowserControl.Navigate(
(ShelObject)KnownFolders.SampleMusic);



Screen 8: The explorer browser control from the Windows API code pack, running in a sample application window.

New Tools for a New UI
With WPF 4 and the Windows API code pack, you can tap into the coolest native Windows 7 features using the full Visual Studio 2010 UI and without once having to leave managed code. That's going to be a big win for developers looking to give their applications an up-to-date Windows 7 look and feel.

   
Steve Apiki is senior developer at Appropriate Solutions, Inc., a Peterborough, NH consulting firm that builds server-based software solutions for a wide variety of platforms using an equally wide variety of tools. Steve has been writing about software and technology for over 15 years.
Blogs
Visual Studio
Extensibility
This gallery showcases products and extensions that complement Visual Studio and Visual Studio Team System.
Hilton Giesenow demonstrates how to add branding for your VSPackage and have that branding appear in the Help...About screen and the Visual Studio start-up splash screen.
View this series of tutorial technical articles on Codeplex for learning Visual Studio extensibility-related topics.