Understanding the change in mindset when switching from WinForms to WPF

October 12, 2012

One of the biggest hurdles I find WinForms developers struggling with when learning WPF and the MVVM design pattern, is understanding the shift in thought process that is used for WPF/MVVM development.

Here’s the best way I can summarize the difference:

  • In WinForms, your forms and UI objects are your application.
  • In WPF/MVVM, the class objects you build are your application, while UI objects are nothing more than a user-friendly interface for interacting with your application objects.

Example

For example, suppose we were asked to make a simple Registration form that takes down a user’s Name, Email Address, and asks them if they want to receive Special Offers or not.

A WinForms developer’s thought process might be to think “I need a Window that contains a TextBox for name, TextBox for email, CheckBox for if they want special offers or not, and a Button to submit the form. When the Submit button is pressed, the data is taken from the UI objects, and saved to the database.”

Winforms Developer's Thought Process

In contrast, a WPF developer’s thought process is “I need a Window that contains a RegistrationForm object. This class needs a string for the Name, a string for the EmailAddress, a boolean property for if they want special offers or not, and a Command to submit the data.”

WPF Developer's Thought Process

But of course WPF doesn’t know how to draw a class of type RegistrationForm, so we’ll have to tell it how to draw the RegistrationForm object using a Template. This template would probably render the Name and EmailAddress properties using TextBoxes, the IsSpecialOffers property with a CheckBox, and provide a Button to run the SaveDataCommand, although that doesn’t have to be the case and is something that can be figured out later.

With WPF, the UI layer and the application layer are so completely separated that you don’t actually need the UI layer at all. If you wanted, you could run your application entirely by test scripts, or through a console window. The actual application layer never needs to reference any UI object to get its data.

Using this concept on a larger scale

In fact, this thought process is used on a much broader scale for the entire WPF/MVVM application.

Want a LoginWindow to come up, and on successful login switch to the MainWindow? No problem, simply start the program with your LoginClass, and on successful Login return the ApplicationClass.

Want to have an application with separate Windows for Products, Orders, and Customers? No problem, create your ApplicationClass to hold a List<T> of available “Window” objects containing the classes representing each “Window”, and include a SelectedWindow property which identifies which window object is currently active.

Of course, WPF needs to know how to draw these class objects, so you’ll need to tell it to use a specific DataTemplate, UserControl, Page, or maybe even Window when rendering these objects.

Summary

This is not meant to be an in-depth look at how WPF is different from WinForms or how to switch from WinForms to WPF, but is more of a brief summary on the change in mindset needed when moving from WinForms to WPF.

With WPF, your application consists of the objects you create, and you use DataTemplates and UI objects to tell WPF how to draw your application components. That’s the opposite of WinForms where you build your application out of UI objects, and then supply them with the data needed.

Once you grasp this key difference, WPF becomes much easier to understand and work with.


What is this “DataContext” you speak of?

July 14, 2012

I frequently see new WPF users confused about what the DataContext is, and how it is used. Hopefully, this can help clarify what the DataContext is, and how it is used.

What is the DataContext?

In WPF, there are two layers to an application: the UI layer and the Data layer.

The Data layer for an application starts out as null, and you can set it using the DataContext property. All UI objects will inherit their DataContext from their parent unless you specify otherwise.

When using the Model-View-ViewModel (MVVM) Design Pattern, the DataContext (Data Layer) is your application, while UI objects, like Buttons, Labels, DataGrids, and even Windows, are all just user-friendly items that allow a user to easily interact with the DataContext, which is your actual application and is typically comprised of ViewModels and Models.

How is it used

Whenever you do a basic binding in WPF, you are binding to the DataContext.

For example, when you write

<Label Name="myLabel" Content="{Binding Path=Name}" />

you are binding to myLabel.DataContext.Name, and not to myLabel.Name.

Other binding properties, such as ElementName or RelativeSource, can be used to tell the binding to lookup the property in something other than the current DataContext.

An Example

Lets start with a regular Window. Without setting the DataContext, the window still displays but there is no data behind it.

<Window x:Name="MyWindow" ...>
   ...
</Window>

Now suppose we set the DataContext to an object of type ClassA in the code-behind when this Window initializes:

public partial class MyWindow: Window
{
    public MyWindow()
    {
       InitializeComponent();
       this.DataContext = new ClassA();
    }
}

Now the data layer behind that the Window is an object of type ClassA.

If ClassA has a property called Name, I could add a Label to the window and bind it to Name property of the DataContext, and whatever value is stored in ClassA.Name would get displayed.

<Window x:Name="MyWindow" ...>
   <Label Content="{Binding Name}" />
</Window>

Now, suppose ClassA has a property called ClassB, and both classes have a property called Name. Here is a block of XAML which illustrates how the DataContext works. It also includes an example of how a control would refer to a property not in its own DataContext.

<!-- DataContext set to ClassA in initialization code -->
<Window x:Name="MyWindow"> 

    <!-- DataContext here is not specified, so it's inherited 
         from its parent's DataContext, which is ClassA -->
    <StackPanel> 

        <!-- DataContext inherited from parent, which is 
             ClassA, so this will display ClassA.Name -->
        <Label Content="{Binding Name}" />

         <!-- DataContext is still ClassA, however we are 
              setting it to ClassA.ClassB with a binding -->
        <StackPanel DataContext="{Binding ClassB}">

            <!-- DataContext inherited from parent, which is 
                 ClassB, so this will display ClassB.Name -->
            <Label Content="{Binding Name}" />

            <!-- DataContext is still ClassB, but we are 
                 binding to the Window's DataContext.Name, 
                 which is ClassA.Name -->
            <Label Content="{Binding 
                       ElementName=MyWindow, 
                       Path=DataContext.Name}" /> 
        </StackPanel>

        <!-- We've left the StackPanel with its DataContext 
             bound to ClassB, so this Label's DataContext 
             is ClassA (inherited from parent StackPanel), 
             and we are binding to ClassA.ClassB.Name -->
        <Label Content="{Binding ClassB.Name}" />
    </StackPanel>
</Window>

As you can see, all the basic bindings look for their value in the data layer (DataContext) of the UI object

Summary

So to summarize, WPF applications have two layers: the UI layer and the Data layer. The data layer for an application starts out as null, and can be set using the DataContext property. UI objects without a DataContext set will inherit their data layer from their parent object. Bindings are used to look up values in the data layer, and display them in the UI layer.

When using the MVVM design pattern, the data layer is your application, while the UI layer just provides a user-friendly way to access the Data layer.


Validating Business Rules in MVVM

January 22, 2012

I’ve always thought that raw data validation should occur in the data Model, while Business Rule validation should occur in the ViewModel.

For example, verifying that a UserName is no longer than X length long should occur in the data model, while verifying that the UserName is unique would occur in the ViewModel. The reason for this is that the User Model is simply a raw data object. It doesn’t contain any advanced functionality like database connectivity, or knowing about other User objects. It’s a selfish little thing which only cares about it’s own data.

Since I use IDataErrorInfo for my validation and like to expose the entire Model to the View from my ViewModel, this presents a problem. Using the above example, I could bind a TextBox to SelectedUser.UserName, and it would automatically show an ErrorTemplate if the string was too long, however it wouldn’t show an error template if the UserName already exists.

After some thought, I decided to add a Validation Delegate to my Models to solve this problem. This is a delegate which ViewModels can use to add Business Logic Validation to its Models.

In the above example, the UsersViewModel might look like this:

public class UsersViewModel
{
    // Keeping these generic to reduce code here, but they
    // should be full properties with PropertyChange notification
    public ObservableCollection<UserModel> UserCollection { get; set; }
    public UserModel SelectedUser { get; set; }

    public UsersViewModel()
    {
        UserCollection = DAL.GetAllUsers();

        // Add the validation delegate to the UserModels
        foreach(var user in UserCollection)
            user.AddValidationDelegate(ValidateUser);
    }

    // User Validation Delegate to verify UserName is unique
    private string ValidateUser(object sender, string propertyName)
    {
        if (propertyName == "UserName")
        {
            var user = (UserModel)sender;
            var existingCount = UserCollection.Count(p => 
                p.UserName == user.UserName && p.Id != user.Id);

            if (existingCount > 0)
                return "This username has already been taken";
        }
        return null;
    }
}

The actual implementation of my IDataErrorInfo on my Model class would look like the code below. It’s generic, so I usually put it into some kind of base class for my Models.


    #region IDataErrorInfo & Validation Members
    
    #region Validation Delegate
    
    public delegate string ValidationDelegate(
        object sender, string propertyName);
    
    private List<ValidationDelegate> _validationDelegates = new List<ValidationDelegate>();
    
    public void AddValidationDelegate(ValidationDelegate func)
    {
        _validationDelegates.Add(func);
    }

    public void RemoveValidationDelegate(ValidationDelegate func)
    {
        if (_validationDelegates.Contains(func))
            _validationDelegates.Remove(func);
    }
    
    #endregion // Validation Delegate
    
    #region IDataErrorInfo for binding errors
    
    string IDataErrorInfo.Error { get { return null; } }
    
    string IDataErrorInfo.this[string propertyName]
    {
        get { return this.GetValidationError(propertyName); }
    }
    
    public string GetValidationError(string propertyName)
    {
        string s = null;

        foreach (var func in _validationDelegates)
        {
            s = func(this, propertyName);
            if (s != null)
                return s;
        }
    
        return s;
    }
    
    #endregion // IDataErrorInfo for binding errors
    
    #endregion // IDataErrorInfo & Validation Members

The idea is that your Models should only contain raw data, therefore they should only validate raw data. This can include validating things like maximum lengths, required fields, and allowed characters. Business Logic, which includes business rules, should be validated in the ViewModel, and by exposing a Validation Delegate that they can subscribe to, this can happen.


Navigation with MVVM

December 18, 2011

When I first started out with MVVM, I was lost about how you should navigate between pages. I’m a firm believer in using ViewModels to do everything (unless it’s View-specific code), and that the UI is simply a user-friendly interface for your ViewModels. I did not want to create a button on a page that has any kind of code-behind to switch pages, and I didn’t like the idea of my navigation being spread out throughout all the ViewModels.

I finally came to realize the solution was simple: I needed a ViewModel for the Application itself, which contained the application state, such as the CurrentPage.

Here is an example that builds on the Simple MVVM Example.

The ViewModel

Usually I name the ViewModel ApplicationViewModel or ShellViewModel, but you can call it whatever you want. It is the startup page of the application, and it is usually the only page or window object in my project.

It usually contains

    List<ViewModelBase> PageViewModels
    ViewModelBase CurrentPage
    ICommand ChangePageCommand

Here is an example ApplicationViewModel that I would use to go with the Simple MVVM Example.


    public class ApplicationViewModel : ObservableObject
    {
        #region Fields

        private ICommand _changePageCommand;

        private IPageViewModel _currentPageViewModel;
        private List<IPageViewModel> _pageViewModels;

        #endregion

        public ApplicationViewModel()
        {
            // Add available pages
            PageViewModels.Add(new HomeViewModel());
            PageViewModels.Add(new ProductsViewModel());

            // Set starting page
            CurrentPageViewModel = PageViewModels[0];
        }

        #region Properties / Commands

        public ICommand ChangePageCommand
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand(
                        p => ChangeViewModel((IPageViewModel)p),
                        p => p is IPageViewModel);
                }

                return _changePageCommand;
            }
        }

        public List<IPageViewModel> PageViewModels
        {
            get
            {
                if (_pageViewModels == null)
                    _pageViewModels = new List<IPageViewModel>();

                return _pageViewModels;
            }
        }

        public IPageViewModel CurrentPageViewModel
        {
            get
            {
                return _currentPageViewModel;
            }
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    OnPropertyChanged("CurrentPageViewModel");
                }
            }
        }

        #endregion

        #region Methods

        private void ChangeViewModel(IPageViewModel viewModel)
        {
            if (!PageViewModels.Contains(viewModel))
                PageViewModels.Add(viewModel);

            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);
        }

        #endregion
    }

This won’t compile right away because I’ve made some changes to it. For one, all my PageViewModels now inherit from an IPageViewModel interface so they can have some common properties, such as a Name.

I also created a new HomeViewModel and HomeView since its hard to demonstrate navigation unless you have at least 2 pages. The HomeViewModel is a blank class that inherits from IPageViewModel, and the HomeView is just a blank UserControl.

In addition, I added an s to ProductsViewModel since it really deals with multiple products, not a single one.

An added advantage to having a ViewModel to control the application state is that it can also be used to handle other application-wide objects, such as Current User, or Error Messages.

The View

I also need an ApplicationView for my ApplicationViewModel. It needs to contain some kind of Navigation that shows the list of PageViewModels, and clicking on a PageViewModel should execute the ChangePage command.

It also needs to contain a control to display the CurrentPage property, and I usually use a ContentControl for that. This allows me to use DataTemplates to tell WPF how to draw each IPageViewModel.

<Window x:Class="SimpleMVVMExample.ApplicationView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimpleMVVMExample"
        Title="Simple MVVM Example" Height="350" Width="525">

    <Window.Resources>
        <DataTemplate DataType="{x:Type local:HomeViewModel}">
            <local:HomeView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ProductsViewModel}">
            <local:ProductsView />
        </DataTemplate>
    </Window.Resources>

    <DockPanel>
        <Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
            <ItemsControl ItemsSource="{Binding PageViewModels}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Name}"
                                Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                CommandParameter="{Binding }"
                                Margin="2,5"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Border>

        <ContentControl Content="{Binding CurrentPageViewModel}" />
    </DockPanel>
</Window>

In this example, I’m using an ItemsControl to display my PageViewModels. Each item is drawn using a Button, and the Button’s Command property is bound to the ChangePageCommand.

Since the Button’s DataContext is the PageViewModel, I used a RelativeSource binding to find the ChangePageCommand. I know that my Window is the ApplicationView, and it’s DataContext is the ApplicationViewModel, so this binding looks up the VisualTree for the Window tag, and gets bound to Window.DataContext.ChangePageCommand.

Also note that I am putting DataTemplates in Window.Resources to tell WPF how to draw each IPageViewModel. By default, if WPF encounters an object in it’s visual tree that it doesn’t know how to handle, it will draw it using a TextBlock containing the .ToString() method of the object. By defining a DataTemplate, I am telling WPF to use a specific template instead of defaulting to a TextBlock.

If you are continuing from the Simple MVVM Example, I moved the ProductView out of a ResourceDictionary and into a UserControl to make this simpler.

Starting the Example

The last thing to do is change App.xaml to make ApplicationView and ApplicationViewModel our startup, instead of ProductView/ProductViewModel.

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        ApplicationView app = new ApplicationView();
        ApplicationViewModel context = new ApplicationViewModel();
        app.DataContext = context;
        app.Show();
    }
}

Run the project and you should see something that looks like the images below, which quickly switches the CurrentPage when clicking on the Navigation buttons.

Screenshot of HomeHome

Screenshot of ProductsProducts

Summary

And there you have it. A simple navigation example with MVVM.

You can download the source code for this sample from here.

Once you get more comfortable with WPF, I would recommend looking into using a Messaging System, such as MVVM Light’s Messenger, or Microsoft Prism’s EventAggregator to broadcast ChangePage commands from any ViewModel so you wouldn’t need to find the ApplicationViewModel to execute the ChangePageCommand, however that’s for another day.

<< Back – A Simple MVVM Example
>> Next – Communication between ViewModels


Navigation with MVVM

July 17, 2011

NOTE: I have re-written this article here to provide a better example, and some code samples.


When I first started out with MVVM, I was lost about how you should navigate between pages. I’m a firm believer in using ViewModels to do everything (unless it’s View-specific code), and that the UI is simply a user-friendly interface for your ViewModels. I did not want to create a button on a page that has any kind of code-behind to switch pages, and I didn’t like the idea of my navigation being spread out throughout all the ViewModels.

I finally came to realize the solution was simple: I needed a ViewModel for the Application itself, which contained the application state, such as the CurrentPage.

The ViewModel

Usually I name the ViewModel ShellViewModel or AppViewModel, but you can call it whatever you want. It is the startup page or window in the application, and is usually the only page/window object in my project.

It looks something like this:

    public class ShellViewModel : INotifyPropertyChanged
    {
        private ICommand _changeViewModelCommand;

        private object _currentViewModel;
        private List<object> _viewModels = new List<object>();

        public ShellViewModel()
        {
            ViewModels.Add(new HomeViewModel());
            CurrentViewModel = ViewModels[0];
        }

        private void ChangeViewModel(object viewModel)
        {
            if (!ViewModels.Contains(viewModel))
                ViewModels.Add(viewModel);

            CurrentViewModel = ViewModels.FirstOrDefault(vm => vm == viewModel);
        }
    }

I have omitted the public property implementation and the INotifyPropertyChanged interface methods for sake of readability. The public properties are your standard get/set properties that raise a PropertyChange notification, and the public ChangeViewModelCommand points to the ChangeViewModel method.

The View

I also need a ShellView for my ShellViewModel, so this is what it usually looks like:

<Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Header -->
        <TextBlock Text="Application Name" FontWeight="Bold" FontSize="24" />

        <Line Grid.Row="1" Stroke="Black" Margin="0,5" StrokeThickness="1" Stretch="Fill" X2="1" />        <!-- Content -->
        <ContentControl Grid.Row="2" Content="{Binding CurrentViewModel}"/>
</Grid>

It contains a standard frame for the application, in this case the application name with a horizontal line under it, followed by the CurrentPage in a ContentControl. When a page is displayed in the ContentControl, WPF will lookup the appropriate DataTemplate to use to display that ViewModel (page).

Changing Pages

The ChangePage command can either be called directly through the XAML using something like this:

<Button Command="{Binding RelativeSource={RelativeSource
            AncestorType={x:Type Window}},
            Path=DataContext.ChangeViewModelCommand}
        CommandParameter="{Binding EditCustomerViewModel}"
        />

or you can use an Event system such as PRISM’s EventAggregator or MVVM Light’s Messenger, and the ViewModels would raise a ChangePage event. I prefer to use an Event system personally, but use whatever works for you.

For more on switching between Pages/Views, see this article


Definition of a DependencyProperty

July 17, 2011

I was recently asked what a DependencyProperty was and how it was different than a regular Property. The MSDN definition says the DependencyProperty class “represents a property that can be set through methods such as, styling, data binding, animation, and inheritance”, but that doesn’t really tell you what a DependencyProperty is, and why it is such an important part of WPF.

The real reason DependencyProperties are so special, is they are not meant to contain a value. Instead they are meant to contain a pointer, or address, of another value.

Instead of saying “This TextBox’s text is going to be Foo”, you end up saying “This TextBox’s text points to a string over here which currently contains Foo”.

The power in this is that it allows you to manipulate the source value without knowing about or altering the UI. If PropertyChange notification is setup, the UI will automatically display a new value without anyone ever touching it.

For example, suppose you had an online shopping application. The User’s Name is displayed in the welcome message, in the top right corner by the My Account link, and on the bottom in the Suggestions for <UserName> section. If the current user changes, you simply have to change a single property to the new value, and anywhere that displays the UserName will be updated automatically. You don’t need to remember which UI fields need to be updated or to change them all manually in the code.

So my definition of a DependencyProperty is a property that depends on another for its value.


Communication between ViewModels with MVVM

June 5, 2011

Communication between ViewModels can be tricky at first glance, but there are some easy frameworks and patterns that can help you out.

For example, lets say you had a ShellViewModel that controlled your entire application, and it has an Exit command. Now lets say one of the sub-view-models in the application would like to call this exit command.

The easiest way is through a Relative Binding to the Window’s DataContext.ExitCommand.

<Button Command="{Binding 
    RelativeSource={RelativeSource AncestorType={x:Type Window},
    Path=DataContext.ExitCommand}}

Of course, this only works well if you can find the control containing the command you want through a binding.

Enter the Event System

Another way is through a loosely coupled event system. I would recommend either MVVM Light’s Messenger or Microsoft Prism’s EventAggregator. You could always build your own event system as well if you really wanted to.

Both event systems makes me think of a paging system. Any ViewModel can broadcast a message, and any ViewModel can subscribe to receive broadcasted messages. Messages are often packaged into different types, so a ViewModel can subscribe to only listen for specific message types such as CloseApplicationMessages.

This kind of loosely coupled event system is ideal for MVVM because the ViewModels don’t need to know about each other to be able to do their job.

Using either of these systems, your ViewModel that handles the event would subscribe to receive a specific message type. It would tell the event system that if a message of type X is broadcasted, send it to a specified delegate method. The ViewModel that wishes to raise the event simply has to broadcast the message and include any parameters needed in the body of the message.

Example using Prism’s EventAggregator

// Subscribe
eventAggregator.GetEvent<CloseAppliactionMessage>().Subscribe(ExitMethod);

// Broadcast
eventAggregator.GetEvent<CloseAppliactionMessage>().Publish();

(I also have some code posted here which simplifies PRISM’s EventAggregator for smaller applications)

Example using MVVM Light’s Messenger

//Subscribe
Messenger.Default.Register<CloseAppliactionMessage>(ExitMethod);

// Broadcast
Messenger.Default.Send<CloseAppliactionMessage>()