Developing application with WPF and Windows 7 (Part II)

In my previous post I talked about how to integrate some of the Windows 7 features (specifically Overlay Images and Taskbar Progress) in a WPF application we created for a screencast (in Spanish). In this post I will go over the remaining features I have yet to cover. These are:

  • How to: Show a thumbnail of the application
  • How to: Use Thumbnail Toolbar buttons
  • How to: Open a new application with the Jumplist

Last time we ended up with this application, so you might be interested in downloading it, since all changes shown in this post will be done to it.

How to: Show a thumbnail of the application

One of the cool features in Windows 7, is that you can show a clipped thumbnail preview of your application instead of one for the entire window. We thought our application was identified by snowboards, so we decided to show the selected snowboard in the taskbar preview.

To set the custom preview, we are going to need the Window's handle. However, as WPF Windows do not have a handle, we are going to add the following code in the Shell.xaml codebehind:

private IntPtr handle;
        public IntPtr Handle
        {
            get
            {
                if (this.handle == IntPtr.Zero)
                {
                    WindowInteropHelper interopHelper = new WindowInteropHelper(this);
                    this.handle = interopHelper.Handle;
                }

                return this.handle;
            }
        }

After that, we can add code like this in the Shell Load to clip our window and show the desired part of it:

private void Shell_OnLoad(object sender, RoutedEventArgs e)
        {
            this.InitializeConnectionMonitor();
            this.InitializeRequestManager();
            this.InitializeServiceAgent();

            Rectangle clippingRect = new Rectangle(
             new System.Drawing.Point(552, 89),
             new System.Drawing.Size(210, 310));

            Taskbar.TabbedThumbnail.SetThumbnailClip(this.Handle, clippingRect);
        }

As you can see, we hardcoded the values to clip the rectangle. However, you can simply calculate to obtain code that will work in any display.

If you run the application you should be able to see a small preview of the board when hovering over the application in the taskbar.

Note: The thumbnail custom preview might not be visible in all versions of Windows 7. Running in VPC environment it also does not work.

How to: Use Thumbnail Toolbar buttons

Thumbnail buttons are a really useful feature, because they allow you to execute different operations in your application without even having to open it. For the snowshop scenario we decided to add two buttons, one that would pick the next snowboard and another one for the previous.

We first  need to define both buttons for the entire scope of the Shell.xaml class:

        private readonly ThumbnailButton buttonPrevious;
        private readonly ThumbnailButton buttonNext;

In the Shell's constructor we create the buttons and assign their respective icons:

        public Shell()
        {
            this.InitializeComponent();

            this.buttonNext = new ThumbnailButton(new Icon("images\nextArrow.ico"), "Next Image");
            this.buttonPrevious = new ThumbnailButton(new Icon("images\prevArrow.ico"), "Previous Image");
        }

Now we have to handle the click event of the buttons and add them. We placed this code in the Shell Load handler:

private void Shell_OnLoad(object sender, RoutedEventArgs e)
       {
           this.InitializeConnectionMonitor();
           this.InitializeRequestManager();
           this.InitializeServiceAgent();

           Rectangle clippingRect = new Rectangle(
            new System.Drawing.Point(552, 89),
            new System.Drawing.Size(210, 310));

           Taskbar.TabbedThumbnail.SetThumbnailClip(this.Handle, clippingRect);

           this.buttonNext.Click += this.ButtonNext_Click;
           this.buttonPrevious.Click += this.ButtonPrevious_Click;

           Taskbar.ThumbnailToolbars.AddButtons(this.Handle, this.buttonPrevious, this.buttonNext);
       }

As you might have noticed, the handlers for the events are yet to be written, so let's get to it:

private void ButtonPrevious_Click(object sender, EventArgs e)
        {
            int newIndex = BoardList.SelectedIndex - 1;

            if (newIndex > -1)
            {
                this.BoardList.SelectedIndex = newIndex;
            }
        }

        private void ButtonNext_Click(object sender, EventArgs e)
        {
            int newIndex = BoardList.SelectedIndex + 1;

            if (newIndex < BoardList.Items.Count)
            {
                this.BoardList.SelectedIndex = newIndex;
            }
        }

But we also want to disable the Previous button when standing in the first board, and disable the Next button when the last board is selected. This can be easiliy achieved by adding the event handler declaration in XAML:

<ListBox x:Name="BoardList" ItemsSource="{Binding Source={StaticResource SnowboardTables}}"
      IsSynchronizedWithCurrentItem="True" Style="{StaticResource BoardListStyle}" SelectionChanged="BoardList_SelectionChanged"/>

And writing code like this for the handler:

private void BoardList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
       {
          this.buttonPrevious.Enabled = this.BoardList.SelectedIndex > 0;
          this.buttonNext.Enabled = this.BoardList.SelectedIndex < BoardList.Items.Count - 1;
       }

As you can see adding code to interact with your applcation via Thumbnail Toolbar buttons is really straightforward, and if you press F5, you should be able to see the Snowboard in the Thumbnail preview spinning as your press the different thumbnail buttons to change the boards.

You can see an image below with the outcome of the application after both additions (Thumbnail Toolbar Buttons and Thumbnail image).

How to: Open a new application with the Jumplist

As you might have noticed the application allows you to sell more than one board at the same time, but it does not provide the total price of the purchase. That is why a feature that might come in handy is having the windows calculator launched from the application's Jumplist . The Jumplist is like the application's start menu, and many useful features can be implemented with it.

To use the Windows 7 Jumplist in your application, you first have to set the application's ID, which is the unique identifier of your application (it is a string). The following code, which should be placed in the App.xaml file, will add a link to the calculator in the SnowShop's jumplist:

protected override void OnStartup(System.Windows.StartupEventArgs e)
       {
           Taskbar.AppId = Settings.Default.AppID;
           JumpList jumpList = Taskbar.JumpList;

           CustomCategory helperCategory = new CustomCategory("Shop Helpers");
           jumpList.CustomCategories.Add(helperCategory);

           JumpListLink taskBarLink = new JumpListLink();
           taskBarLink.Title = "Run Calculator";
           taskBarLink.Path = @"%windir%\system32\calc.exe";

           helperCategory.JumpListItems.Add(taskBarLink);
           jumpList.RefreshTaskbarList();

           base.OnStartup(e);
       }

Outcome

You can download the code for the entire demo (including all the modifications explained in this post) from the link below.

Disclaimer

This code is provided “AS IS” with no warranties, and confers no rights.

Download

You can get source code here: SnowShopW7.zip.

I hope this couple of posts were useful for you when developing with WPF and Windows 7.