Introduction

The Windows Presentation Foundation provides a fantastic way to develop your applications. However, getting started with WPF can be daunting. Data binding, MVVM, XAML, Pixel Shaders, Control Templates, Styles, Resources, and Triggers are all terms that may well be unfamiliar.

This article will help you get started with WPF. We'll create a simple application, going over points of interest blow by blow. By the end of the article, you will be comfortable with some of the core concepts of WPF development, and you'll be well on the way to being able to harness the power of WPF to create stunning applications.

One of the great things about WPF is that it encourages you to use a sensible pattern for writing software - separating content from design, keeping the business logic away from the UI. You will write code that is well organised, easily testable, and maintainable.

Background

The code in this article is C#. Visual Basic code will be very similar. If there is enough interest, I will update it with VB code. I am using the latest platforms and technologies - Expression Blend 4, Visual Studio 2010, and the .NET Framework 4.0.

Creating a New Project

Enough preamble. Let's dive in and get started. We'll start simple and build a skeleton application, then we can take our basic application and refine it. Rather than being bombarded with technical details and abstracts, we're going for a very hands on approach.

First of all, open Expression Blend 4 and choose 'New Project'. I'm calling this one WpfStepByStep1 - any name will do!

We've got some files. A bit of C# and a bit of XAML. XAML is Extensible Application Markup Language. We use it to lay out windows and UI elements. XAML is quite similar to HTML; it allows us to lay out windows, arrange controls, and more. We'll be using XAML a lot, but for now, let's simply see what we've got. Hit F5, or go to Project > Run Project.

There's not much to see, but we've got quite a bit here really. A new window, a blank space for us to arrange content, and the typical features found in a Windows application (close button and so on). One thing is worth noticing - we can re-size, minimise, and maximise the window. In the world of HTML, we rarely know how big a user screen will be - or how big their browser window will be. Because of this, we rarely rely on absolute positioning, such as 'this button is 30 pixels from the left'. We try to arrange a window or page so that the content can be re-sized gracefully. WPF can do this very well - we're going to make sure that our app works whether the window is small or large.

Adding Some Controls

If you are completely unfamiliar with WPF and Expression Blend, now is a good time to have a play. The 'Assets' panel on the left has a 'Controls' section. Click on it. A set of controls is now displayed in the Assets panel.

We have access to a variety of familiar and unfamiliar controls. There are also shapes to play with. Later on, we'll even look at effects and animation. The Expression Blend design window is geared towards UI design - visual hints are provided as items are moved and resized. In fact, some of the data presented may seem a bit confusing. For now, we'll accept that we can quickly drop controls onto our window.

Delete any controls that you have added - we're going to create a functional application and will need a clean slate. For this article, we're going to create an Address Book. It's not the most original idea, but is simple enough for us to look at some of the features we'll be interested in.

Getting Started with the Address Book

We've decided to write a simple address book application, to allow us to manage some information about our contacts. Typically, this is where we'd start to think about things like the information we want to present, how the UI might look, functional requirements and so on that we need to implement. For now, I'm going to speed things up by giving you the brief:

I want a simple Address Book app. I need the facility to:

Look at contacts.

Add new contacts.

View simple contact details - name, email address, and phone number.

On top of that, I have decided that I want it to look roughly like this:

If you're interested in how I made the image above, then let me know. Expression Blend has a powerful UI prototyping tool called 'SketchFlow' that makes it easier than ever to mock up UI designs, as well as add animation, gather feedback from clients, and more. This is a large topic in itself, but if there is enough interest, then I'll write an article in this series focused on SketchFlow.

The hands-on approach is great for a project like this. The sketch above is basic, but complete enough for us to have a first crack at the UI. Follow the steps below:

Find the 'Text Block' control in the Assets panel (there's a handy search box if you can't find it). The Text Block is used for chunks of text - likes a Static in Win32/MFC, or a Label in Windows Forms. Drag the Text Block onto the design surface.

Go to selection mode by selecting the darker arrow from the top of the toolbar on the left. Click on the text block and open the 'Properties' panel on the right hand side. Find the 'Text' property in the 'Common Properties' tab, and change it to 'Address Book'.

Drag a 'List Box' control onto the left hand side of the window - this is where we'll show the list of contacts.

Create another text block on the right hand side of the window and set the text to 'Contact Details'.

Create the three text blocks shown in the UI prototype.

Hint: Speed things up by dragging copies. Select a text block and hold the Alt key. Drag the text block somewhere else. Release, and a copy will have been created. This works even when you've got groups of controls selected.

Drag three 'Text Box' controls onto the window. Arrange these just like in the UI prototype.

Finally, drag a 'Button' control onto the design surface and set its content to 'Create a New Contact'. Position it as in the prototype.

You should now have something like this:

At this stage, you could have a closer look at the Properties panel. The controls we've laid out can be modified extensively using the Properties panel. We can change fonts, colours, brushes, visual effects, and more. Remember, at the bottom of each panel in the Properties window is a small bar - press it for even more advanced properties. Get used to using the search box too - it'll come in handy as you get more familiar with Blend and WPF.

Hit F5. We're off to a good start, the controls are there and positioned appropriately. Re-size the window. Depending on how you laid out your controls, you'll get a variety of behaviour for how controls are repositioned and re-sized. In any case, the re-size behaviour is probably not perfect - we'll come back to this. For now, we'll move on to getting some functionality done.

Creating Objects

From the specification, we have a fairly good idea of what sort of data objects we'll need. A Contact object will hold a name, email address, and phone number. The application as a whole will contain a set of contacts.

In Expression Blend, go to Project > New Item, and create a class file named 'Contact.cs'.

It doesn't get much easier than this. If you have already played around with Model-View-ViewModel, then don't worry - we'll be coming to that soon. For now, we're keeping things as simple as possible.

We're now getting to the first real WPF challenge - where do we put contacts? Are they in the XAML? In the App class? In the MainWindow class? This is the sort of question that causes confusion - you may have heard that the place to put data is in the model and present it with the model view - but what are these entities? And where do they exist? We're going to come back to this shortly; for now, we'll go for what seems to be the quickest solution - then, we'll look at how to do it the WPF way, which it turns out is even quicker!

Finally, we need to tie this into the window. WPF has its own way of doing this, called Data Binding. We'll get into this in detail later on. In a typical WinForms application, we'd probably go through the list of contacts, create a list view item for each one, set the tag to the data object, and insert it into a list box. With WPF, we'll tell the list view 'this is your data' and let it take over from there. We can do that with the data as we have it here, but it's a little bit convoluted. Build the project. Open the MainWindow.xaml file so that you can see the controls. Click on the list box on the left hand side and locate the 'ItemsSource' property. Open the advanced properties by pressing the little square next to it, and choose 'Data Binding'.

We can bind to the 'Contacts' property of the MainWindow object by selecting 'Element' at the top and finding the 'Contacts' property.

Press OK and hit F5. We can see three contact objects in the list control. Not particularly useful. Also, finding that property was a bit tricky. What happens when we have more and more properties and we want to maybe interlink them. This is where MVVM (Model-View-ViewModel) design will come into play.

MVVM

The idea behind MVVM is this: we have three elements to the application:

The Model

The Model is the application data. It could be from a database, a file, memory, or whatever. The model may well contain business logic and some very complicated entities.

The View

The View is the presentation layer of the application. In this case, it is the XAML file that controls what is displayed and how it is rendered.

The ViewModel

The ViewModel is the object that ties the two together. In our case, the ViewModel would contain the list of contacts we're showing, the current contact, and anything else that we might need the view to connect to.

This is the very basic outline of MVVM. As with the previous concepts, we're going to learn this pattern by using it. We know from the above points that a ViewModel is an object that ties the content to the presentation. So, let's go ahead and write one. The view must show the contacts and the details for the selected contact, so we'll put that data in a model view class. Create a new class called 'AddressBookViewModel'.

This class will hold all the data that we're going to present. Delete the 'contacts' member and 'Contacts' property from the MainWindow.xaml.cs file - we don't need them any more. Also remove the lines we added to the constructor adding the contacts.

Where is the ViewModel instance stored? This is another question that causes confusion. Does the View ask for a ViewModel, does the application create the ViewModel and set it into the View? How do we tie it together? The short answer is that we're going to have a single instance of the ViewModel in the window object. But we're going to do it without adding a single line of code. The next few steps are really important - you'll probably use them for every window in your app.

Delete the binding we set before by clicking on the 'Reset' advanced properties popup on the list box 'ItemsSource' property. Build the project. Select the MainWindow in the designer by double clicking on the MainWindow.xaml file in the projects panel. Below it is an 'Objects and Timeline' panel. This shows a visual tree of what is in the window. The window is the top level object. Once it's selected, go to the Properties panel and find 'Data Context'.

Isn't the search feature useful? If you haven't used it, give it a try - it'll save you lots of time. The DataContext can be thought of as the object or data that we're going to be binding UI elements to. It is hierarchical, so by setting it in the window, we set the data context for all of the controls - we can set it once and forget about it. The plan is to set the data context of the window to an instance of the ViewModel - this will greatly simplify things. Click 'New'.

We can set almost anything to be the data context. Search for 'view' or 'viewmodel' and select the AddressBookViewModel class. Choose 'OK'. Now that we've set the data context, select the list box on the left hand side and go back to the 'Items Source' property. Press the Advanced button and choose 'Data Binding'. We can now use the 'Data Context' tab at the top - and we have our AddressBookViewModel object to play with. Select 'Contacts' and press 'OK'.

We are now using the data context and binding directly to the contacts. What has this actually done? Go to 'Split' view by pressing the small icon shown below, at the top right of the window. The data context has been set near the top of the XAML:

This is smart. The object we created in the XAML is available in the code-behind.

Let's get even more clever. In the same way as we set the data binding before, set the bindings below:

For the list box, bind the 'SelectedItem' property to 'Selected Contact'.

In the 'Name' text box, bind the 'Text' property to the 'SelectedContact > Name' property ('SelectedContact' can be expanded to show its members).

In the 'Email' text box, bind the 'Text' property to the 'SelectedContact > Email' property.

In the 'Phone' text box, bind the 'Text' property to the 'SelectedContact > PhoneNumber' property.

Hit F5. We have the list as before - but because we told the list to bind its selected item to the 'SelectedContact' property in our ViewModel, selecting an item in the list sets the 'SelectedContact' property. The three text boxes are bound to various properties of the 'SelectedObject' - so when we change, the text boxes are updated. Edit the text in each of the boxes and change to another contact - then change back. Our changes have persisted - the selected object is simply a reference to one of the items in our 'Contacts' list, so everything ties in together perfectly. Remember - the only code we've done to get the UI of the app working is setting some simple contacts in the constructor - we've actually tied in the text boxes and list control without ever leaving the designer.

Notification of Property Changes

We have missed out on something subtle. If you were to continue building the app with this approach, you'd soon notice something that is lacking - when we change ViewModel properties programmatically, the UI doesn't update. As a demonstration of this, we're going to update the program so that when the window has loaded, the first contact is automatically selected.

Open the MainWindow.xaml file in the designer. In the 'Objects and Timeline' panel, double click on the 'Window' item at the top of the tree to select the main window. Go to the Properties panel and choose 'Events'. The events icon is at the top right, as shown below:

There are a stack of events we can handle, but for now, we want the 'Loaded' event. Find it in the list and double click on the text box to the right of the 'Loaded' label. This will create the event handler for us and will open it in the code editor. Change the event handler to select the first contact.

privatevoid Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
// Set the 'SelectedContact' of the view model to the first contact.
ViewModel.SelectedContact = ViewModel.Contacts[0];
}

Run the program. The first contact isn't displayed as selected. So what's gone wrong?

I'll save you some time with the debugger (which you'd have to use from Visual Studio!). The code you've written is being called, but the UI doesn't know that the SelectedContact has changed. So what do we do?

In a WinForms or Win32 application, we'd need to tell the UI that the object has changed; we might call Invalidate, Refresh or something along those lines. This is is not particularly good; it means that our small chunk of business logic needs to know about the UI, it has to know what to update. What if we need to do lots of things when the selected contact changes? What we'll do is tweak the ViewModel to implement the INotifyPropertyChanged interface. This interface allows us to send a notification when the property changes; anything that has registered to receive this notification will be updated. If we implement this interface in our ViewModel, then the UI will be notified that the property has changed and updates itself accordingly.

When the SelectedContact is set, we check to see if it's being set to something different. If it is, we set it and raise the event. Run the program. The first item in the list is now selected, and the text boxes are all updated.

When do we need to do this? The short answer is almost always. We can ignore the Contact object for now, because we don't change any of its properties programmatically. But if we did, we'd need to use the same approach. In this case, we'd probably wrap it in a ContactViewModel class to keep the ViewModel specifics separate. There's one more change we should make, again shown in bold.

To get this to build, you'll need to add the line using System.Collections.ObjectModel; to the top of the file. An ObservableCollection is a collection that sends notifications when items are added or removed. Now if we change the collection, then the View will be updated automatically. Why don't we need to call the 'NotifyPropertyChanged' function in the 'set' part of the 'Contacts' property? Because we don't change the reference to the collection - we change the items in the collection. So using ObservableCollection will suffice. If we were switching between lots of different collections, we'd need to call the function just like we do for the 'SelectedContact' property.

MVVM

We've now used the Model-View-ViewModel pattern in our application. In our Model, we have a basic Contact object. For our view, we have the MainWindow XAML. And we have a dedicated AddressBookViewModel object to tie the two together. We can keep the business logic and data layer separate to the presentation of the data; when you get used to this pattern, it makes more and more sense. One of the nice things about WPF is that it really forces you into this approach to get the most out of it - it'll help you design and write better code.

Moving On

There are still a few things left to do. For one thing, the list box on the left shows the name of the object it's displaying, but we want the contact name. Select the list box in the designer, and find the 'DisplayMemberPath' property. Set it to 'Name'.

Run the application. We now see the 'Name' property of the Contact object in the list. This is a quick way to get what we want. We could create an 'ItemTemplate' in the XAML that does much more - show the name, the email address below as a hyperlink, and so on, but that is a more advanced topic.

Now that we have the name set as the display member, we can see that we still have a limitation. Changing the name of a contact in the text box on the right doesn't update the list box. We know why now - the property is being changed by the list box, but the property doesn't send a notification when it is changed. We need to change the Contact object so that it derives from ViewModelEntity and sends notifications. Here's the code:

Make the changes and run the program. Now when you change the name and tab out of the control or select another, this list is updated. The Name property is not actually changed until we leave the box.

Adding New Data

We want to get the 'Create New Contact' button working. Select it in the designer, go to the events (in the property panel), and choose 'Click'. Double click the box to create an event hander, and add the code below:

After the initial complexity of setting the data context and creating some view model entities, we can implement business logic very rapidly now. In the code above, we don't tell the UI to update, we don't care whether the view is showing a list or how it displays itself. The bindings we've set up handle that side of things and the XAML controls rendering.

Back to MVVM

As an aside, it is worth pointing out that now that we've got to this stage, we're even closer to an ideal MVVM pattern. The 'Contact' object has actually become, in essence, a 'ContactViewModel' entity. Contact data will probably be stored in a file or database - these will be Contact Model entities - from these, we create Contact ViewModel entities - which might be quite different. For example, the ContactViewModel entity might want to store other data - such as whether it has been changed (allowing the view to show a 'Save Changes' button perhaps).

Rather than starting out with the MVVM pattern, we've moved towards it because we've needed to. Now that we're using it, we can extend this application with ease.

Next Steps

We've still got plenty of work to do on the Address Book application. It doesn't handle resizing well, it doesn't persist data, and looks very basic. But we've covered a lot - creating a new application, using a Data Context and Data Bindings, INotifyPropertyChanged, and ObservableCollections. Hopefully, you have become a bit more familiar with Expression Blend along the way. This is the first in a series of articles I am planning - any feedback would be great - let me know what you like or dislike and anything that's unclear. Where would you like to go from here? E-mail me at dwmkerr@googlemail.com and let me know - I'll write the next step by step based on what it seems people want to learn about next. For example:

Layout: Using Grids and Panels to lay out controls.

Style: Customising controls with styles and templates.

Data: Design-time data, XML, and more CLR.

Visual Studio 2010 vs. Expression Blend 4

Use them together! Expression Blend is great for layout, design, and styling, but Visual Studio is required for anything relating to code that is non-trivial. I always have both open, and use the two concurrently.

This project could be written in the same way using Visual Studio. It has a slightly less powerful data binding editor, and does things like creating data contexts visually less well, but when you're a bit more familiar with XAML, you'll probably end up writing a lot of it by hand. Expression Blend is the choice for designing your UIs, but Visual Studio is generally needed for the code behind.

It would be even better if it worked. As you know, MS is always changing things and VS/Blend 2015 has changed the way things work, so your example and your approach - do not work any longer. So, I was wondering: are you going to update this? If you do, it is much appreciated. Thank you.

I have been reading a lot of WPF articles and books . Most of them start with the Xaml editor which for anyone who is used to Winforms seems daunting.I like the approach you have taken in detailing out the steps.Great job. Have you written other tutorials which you mentioned in the article. Please provide the links if possible

Since some time I've avoided WPF for some reason, mainly because i am quite familiar with Windows Forms.

But starting with WPF now, I also wanted to know why/how to do MVVM manually, and these questions where answered by this article. Moving to a framework like MVVM light or PRISM is all well, but you'll realise their features much better when you've done it the hard way first.

I'd really like a continuation of this article, f.e. including commands, structuring an application etc.Could anyone recommend a book doing it the same way ?

Create data binding dialog does not look like the one pictured here, there is no option "Element" to select, and selecting "ElementName", or any other available choice, does not produce the contents shown in the listboxes in this tutorial.

Your presentation of the proper use of WPF was inspiring, to say the least. I never understood what a lot of things in Blend really meant and I have not seen them explained elsewhere as you did here. I would be very interested in following a series that moves further and further into the intricacies of WPF/Blend x. For now, I am very confused about making user controls. Oh sure, the context menu item is there and it is easy enough to press but how do I make a button that allows me to set most properties in replication but also allows me to set others that are instance unique. For example, the text portion of the button on the UI. Two maybe three days of doing battle with this problem and I am pulling what little hair I have left – out!

Thanks for the comments - there is no part two yet, but I might see if I can get started on one soon If I do, I'll try and make the focus user controls - if you are really struggling BTW then email me the exact details at dwmkerr AT gmail DOT com and I can see if I can help out!

When selecting a contact from the list, and editing the contact using the text boxes, the list item it immediately updated.How would you go about making it so that the list item is not update immediately,. instead the user can click an apply button or whatever to apply the changes to the list items?

Im not asking how to add the button. thats easy. Im asking how you separate the list from the text boxes.Are there common techniques that can be used here?

Glad you liked the article! OK - the next one will cover this, but here's the rough idea:

1. Have the list of items and the selected item in the view model (as it is).2. Have objects in the viewmodel for each of the fields on the screen, so in this case have a string like 'contactName'.3. Bind each of the controls on the right hand side to these new fields, rather than to the selected object directly.4. When the selected object is changed (in the viewmodel 'set' property for it) update the values that you added:contactName = selectedContact.Name;etc5. When some event happens (e.g. 'save the contact' or whatever) update the selected object in the viewmodel from the fields:selectedContact.Name = contactName;

This is the approach I would use. In fact, it's almost necessary in many cases - imagine that the contacts are in a database, you select a contact and change the name, then select another contact and change its name - hit save and it's changed BOTH names - but the user didn't click save after the FIRST change, so may have expected that change to have been discarded.

being true to the 'ideal' of the MVVM approach, the contact name field edits a contact name in the view model - not necessary the selected contacts name. Also, if you are created a NEW contact, there won't BE a selected contact - but the contact name field still needs to work!

i hope this makes sense, the code 'samples' are obviously just to illustrate the idea, i'm at work so have to rush!

give me a shout if you have any problems, the next article will cover laying out the screen properly and things like using 'ICommand' to create 'save' commands and so on

Basically my 'Book' being updated / displayed by the view models was not implementing INotifyPropertyChanged, once I implemented this, everything works as expected.

What im not sure of is.. am I using the Model (Book in my case) correctly.Should I need to implement INPC here?Or should I be wrapping the Book model with a Book ViewModel and using that in the other view models?

fyi...looks like clicking those links will require you to login to google..ill try and find somewhere else to put it if anyone wants it.

The viewmodel might then expose commands (such as 'Save changes') that would use the model to save the data store - think of the model as the part that actually handles accessing the data from whereever you store it (such as a database, or file).

Given this approach, logic to do with presenting a book is in the viewmodel, separate from logic to do with persisting a book

Very informative article. I gained good understanding.. this coming from some1 with no experience in WPF whatsoever. I did run into a situation. When i dragged in a listBox it automatically came with the following code:<ListView x:Name="AddressBookList" Margin="8,29.277,248,33.723" ItemsSource="{Binding Contacts}" SelectedItem="{Binding SelectedContact}" DisplayMemberPath="Name"> <ListView.View> <GridView> <GridViewColumn/> </GridView> </ListView.View></ListView>

Altough this just added some formatting, the DisplayMemberPath option did not work and I got the object name instaead of the "Name" property even though DisplayMemberPath was set.

Thx a lot - my vote is 5This is a very clear straightforward explanation for how ist works together, without a lot of bulky stuff like Entity-FW, WCF, RIA, or a lot of Classes doing things behind the scene ...That's what I like!