Creating a Desktop Application Using WPF
Our goal with this last tutorial is a little different than the previous seven tutorials. We actually aren't going to be running code in Silverlight with this tutorial - instead we will be using WPF and .NET 3.5. We'll be taking the existing search application code we've written to run inside Silverlight in the browser, and re-use it to also run as a Windows desktop application.
Silverlight ships with a compatible API subset of what is in the full version of the .NET Framework. One goal with this is to enable developers to learn a common programming model and tool-set and be able to re-use skills, code and content across RIA web applications, rich Windows desktop applications, and Office solutions.
Below are the steps I took to re-use our existing Silverlight application code (which runs in the browser) to build a Windows desktop application version (which runs outside the browser).
Step 1: Create a New WPF Desktop Application
We'll start by creating a new WPF Desktop Application using VS 2008. We'll name it "DiggDesktopSample":
This will create a project inside VS with two files - an App.xaml, and a Window.xaml:
Note that this project structure is very similar to the Silverlight one we created in Tutorial 1 of this series (which had an App.xaml and a Page.xaml file).
Step 2) Copy Existing Digg Application Code into the WPF Application
We'll copy/paste our existing DiggApplication Silverlight code into our new DiggDesktopSample Windows project:
Step 3) Fix Up a Few Issues
I had to make two changes to get our existing Digg sample code to compile:
1) I needed to add a line to the networking code to manually specify a "user-agent" header. The Digg REST API will return an error if no user-agent header is sent - and by default Windows applications don't send this if you use the WebClient API (whereas browser hosted applications will send it).
2) I had to change the <HyperlinkButton> control in our user control to be a <TextBlock>. This is a new control in Silverlight 2 that isn't in the full WPF yet (we will add them in the future though). I did not have to change any of the code that worked with these controls, though, nor my network, LINQ to XML, nor databinding code.
Once I made these small tweaks the project compiled clean.
Step 4) Hosting the Digg Application in a Desktop Window
I then opened up the Windows1.xaml file in the desktop project (which is the default Window that loads when the application starts).
I updated the Window title to be "Digg Desktop Version" and expanded the default Width and Height of the Window.
I then added our Page.xaml user control from our previous Digg Silverlight project as the root control in the Window. This will cause it to be visible and loaded when the Window loads. I did not have to change the Page class code or rename anything in it. Because it derives from UserControl it can be hosted just fine inside any WPF Window or Control.
Step 5) Running the Application
I was then able to run our new Digg Desktop Application. All functionality worked the same as the Silverlight version and the application behaved the same:
And when a story is selected from the list, the details user control is displayed:
There are a few cosmetic styling differences between the browser and desktop version. This is primarily because WPF by default inherits default styles (fonts, colors, scroll bars, etc) based on the operating system theme a user currently has selected, whereas Silverlight has a default theme that we use for all operating systems. If we wanted to make the desktop version and the browser version absolutely identical we could do so by being more explicit with our Styles and Control Templates - otherwise the desktop version will adapt slightly based on the user's OS theme.
We'll be coming out with more detailed notes and suggested best practice guidance for sharing code across Silverlight and WPF projects in the future. I think you'll find that the skills and knowledge you learn when building Silverlight applications will transfer very well to full WPF projects. We are also striving for a very high compatibility bar that will enable good code re-use across solutions, and enable controls, content and code to be easily shared and leveraged.
Hope this helps,