This project is read-only.

WPF MVVM Helper Library

Getting started with Windows Presentation Framework and Model-View-ViewModel

Purpose & Introduction

WPF and MVVM are tightly bound together. If you have done anything beyond simple MVVM “Hello World” program you have discovered that MVVM does generate a lot of code; and much of it follows some pretty repetitive patterns.
The purpose of this helper library is to help you gain the functionality of these common behaviors while allowing you to concentrate on building your software solution.

There is nothing in this library that is new or especially brilliant. Like ScrimpNet.Com Developer Library, this library is a tool to help reduce tedium and repetition of certain tasks.

Usage

Do you want to know more about the classes, design, and methods? They are after this section. (We guessed you are probably more interested in actually using this thing than reading about how “brilliant” we are in our design and execution.)
This document assumes you have some idea how to MVVM works. In short the ViewModel replaces virtually all data and logic that is traditionally found in the code behind files of either web forms or Windows forms.
Using WPF binding you connect your XAML file to the ViewModel. Most applications have these features in common:

  • Data Properties to display in or that are modified by the UI
  • Validation Behavior
  • Command properties being bound to action scripts within the ViewModel.
  • Raising the PropertyChangedEvent to notify WPF that a ViewModel property has changed and WPF should react to the change
  • Enable/Disable parts of the UI based on changes in the state of the ViewModel.

ScrimpNet.Presentation library encapsulates much of this behavior for you; but don’t worry, there’s still plenty of work for you to do. WPF excels at needing an extensive network of code wiring; this library only hides a small portion of it.
MVVM views are usually mated with a specific ViewModel that supports it. So let’s look at using ScrimpNet.Presentation library to help build out a ViewModel.
(NOTE: You must have a reference to ScrimpNet.Presentation library. We recommend a ‘Project’ reference since you can change and debug the library more easily.)

Building A View Model With Help From ScrimpNet.Presentation

1) Make your view model a descendent of ViewModelWindowBase or ViewModelClosableWindowBase. What does that do? These classes give you immediate access to:

  • IDisposable – so you can clean up any database connections, image objects,or other stuff you accumulate along the way
  • INotifyPropertyChanged – required if you want the View and your ViewModel to share data back and forth
  • IDataErrorInfo – so WPF can link your ViewModel into its internal error handling and validation framework
  • ICommand collection management
public class MyViewModel : ViewModelClosableWindowBase //get all the goodies
{
    public MyViewModel()
    {
        //do some magic here
    }

        private string _myProperty;
        /// <summary>
        /// Sample property that is going to be bound to XAML view
        /// </summary>
        public string MyProp
        {
            get
            {
                return _myProperty;
            }
            set
            {
                if (string.Compare(_myProperty, value) != 0)
                {
                    _myProperty = value;
                    RaisePropertyChanged("MyProp");  //tell ViewModelObjectBase to raise a PropertyChangedEvent (magic here)
                }
            }
        }
} //class


RaisePropertyChanged() method does all the repetitive heavy lifting for you. (Note: It seems that with WPF you need to explicitly trigger the OnPropertyChanged event. This means you can’t use .Net’s automatic property {get;set;} syntax.)

There are several data validation strategies within the WPF/MVVM framework. One of the common approaches is to implement IDataErrorInfo interface on the object that is being bound to the view. If your object inherits from ViewModelObjectBase you get this functionality. Since ViewModelWindowBase inherits from ViewModelObjectBase you have most of the work done for you. Simply override the thisstring propertyName method and respond with any error messages you want to throw. There is no ‘special sauce’ here; just a standard implementation of the interface that WPF natively takes advantage of. (You can learn more about IDataErrorInfo here: http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo.aspx
For a simple example:

/// <summary>
/// Called by WPF validation framework to ensure validity of object. For IDataErrorInfo implementation.
/// </summary>
/// <param name="propertyName">Name of class property that is being validated</param>
/// <returns>NULL if no error or some kind of message if propertyName is in an error state</returns>
public override string this[string propertyName] //<== implement your own validation rules
{
    get
    {
        switch (propertyName)
        {
            case "MyProp":
                break;
            default:
                Debug.Fail(TextUtils.StringFormat("Unable to find property '{0}' for validation",propertyName));
                break;
        }
        return base[propertyName];
    }
}

MVVM Command Support With Help From ScrimpNet.Presentation

If you haven’t worked with MVVM commands yet, you will soon. MVVM commands are the actions you want to happen when a user clicks on a button or takes similar actions on the UI. While MVVM purists might shudder, you might consider MVVM commands analogous to OnClick() in ASP.Net and Windows forms.

If you have worked with MVVM commands you know you need to establish:

  • A command property to bind you button to,
  • A command action that will be executed when the button is clicked,
  • (optionally) a CanExecute() method to programmatically enable/disable a button.


ScrimpNet.Presentation provides a simple command dictionary and some nice helper constructors to quickly build up commands while maintaining a clear logic stream.

As a pattern we typically register our commands from within the ViewModel’s constructor. It just keeps things clean but there is no strong reason you can’t do it elsewhere.

public MyViewModel() 
: base("MyViewModel") //<==All ViewModelObjectBase objects require a textual name.  Text content does not really matter
{
    // register commands for later usage using convenient Adder methods
    Commands.Add("DeleteEntry", deleteAction, deleteCanExecute);  //<== add command with both action and enable/disable logic
    Commands.Add("CancelEdit", cancelAction); //<== add command with only Action.  Always enabled
    Commands.Add(new SimpleCommand()); //<== add your own specialized command
}


Now comes the standard MVVM command plumbing. There’s not much we have done to reduce or eliminate this. These samples have nothing to do with ScrimpNet.Presentation library but we’ve included them just to help round out the sample code. (Method comments and other code removed for logic clarity.)

public ICommand DeleteCommand //<== WPF buttons binds to this
{
    get
    {
        return Commands["DeleteEntry"]; // get ICommand registered in constructor
    }
}
private void deleteAction(object obj) //<== code executed when button is clicked
{
     //do your action code here
}

public bool deleteCanExecute(object obj) //<== WPF periodically polls this value to determine if button should be enabled or disabled.
{
    return Today == Days.Friday && CurrentTime == Time.QuittingTime;
}


Note About Naming Conventions: As a convention we try to name our command hooks using actionRole pattern. While it can sound awkward to the American English ear, naming methods this way helps group the methods closely in VisualStudio’s Intellisense, object explorer, and method explorer. We haven’t found a computer that complains about the unusual arrangement.
Roles are generally names:

  • abcCommand – for properties that expose commands to the View
  • abcAction – for methods that contain code blocks that are executed when View activates command. (usually private)
  • abcCanExecute – for methods that are called by WPF to determine if command is valid for the current state of the ViewModel.


Summary

So we have covered how to use ScrimpNet.Presentation library to embedded common MVVM functionality into your ViewModels and how to use the library too easily (somewhat) register and respond to View commands. The library, among other things, provides an implementation of:
*INotifyPropertyChanged – required if you want the View and your ViewModel to share data back and forth

  • IDataErrorInfo – so WPF can link your ViewModel into its internal error handling and validation framework
  • ICommand collection management

Happy M-V-VMing!

Library Design

When you develop MVVM applications there are two common object types you frequently build:

  1. ViewModels – binds to the view, responds to UI events, and exposes one or more properties of one or more business objects.
  2. Commands – while less command than ViewModels, custom commands are used to clearly define and organize actions originated in the UI.


This library provides a single concrete command: SimpleCommand. SimpleCommand exposes the required ICommand needed by WPF as well as supporting methods from its ViewModel hierarchy provided by the Presentation library. SimpleCommand is probably sufficient for a good portion of use-cases but of course you can easily create your own commands by either extending SimpleCommand or inheriting from ViewModelCommandBase. When you use one of the ViewModel.Commands.Add() methods, the library is creating SimpleCommands in the background.

ViewModels are typically bound to specific XAML ‘windows’, ‘frames’, or ‘pages’. This library uses ‘Window’ as a generic name for these objects. The library exposes two abstract classes your concrete ViewModel should inherit from:

  1. ViewModelClosableWindowBase – Exposes a ‘CloseCommand’ that can be bound to an element (e.g. button) in the XAML. In reality you can bind any button with any action to this command. It is there just for clarity and convenience. (Inherited from ViewModelWindowBase)
  2. ViewModelWindowBase – Maintains a list of ICommand objects the ViewModel needs. (Inherited from ViewModelObjectBase)


All objects inherit from ViewModelObjectBase. This class provides the bulk of interface implementations that are needed for WPF-MVVM applications. This means when you sub-class your ViewModel with one of the abstract Window classes or command classes you get all this functionality for free. Interfaces supported by ObjectBase are: IDisposable, INotifyPropertyChanged, IDataErrorInfo.

Class Functionality Summary

Class Method Description
ViewModelObjectBase (abstract) Implements common functionality shared with all ViewModel Objects
DisplayName Textual description of this instance. Typically used in debugging and/or logging
Error Side effect of implementing IDataErrorInfo. Not used in library. Throws NotImplementedException if called.
Item{“[string]”} Indexer of property name for implementing IDataErrorInfo
ThrowOnInvalidProperty If true(default) library will throw an exception during validation if specified property is not known. (DEBUG only)
RaisePropertyChanged Convenience method to trigger PropertyChangedEvents (if any)
releaseManagedResources allows descendent classes an opportunity to release any managed resources they might be holding. Called when class is being Disposed. (protected virtual)
VerifyPropertyName Throws InvalidOperationException if a public property of that name doesn’t exist (DEBUG only)
ViewModelWindowBase (abstract) Extends ObjectBase by adding a Commands collection suitable for ViewModels that are bound to XAML windows. NOTE: Concrete ViewModels can inherit from this class
Commands List of ViewModelCommandBase that have been registered for this particular ViewModel
ViewModelClosableWindowBase (abstract) Exposes a ICommand object suitable to be bound to XAML button for closing the window this ViewModel is mapped to. . NOTE: Concrete ViewModels can inherit from this class
CloseCommand SimpleCommand that will be executed on close command
RequestClose Code block that will be executed when program wants to close a window. Often the View will inject some kind of window.close() delegate here
SimpleCommand (concrete) Defines a ICommand object that holds both and Action delegate (code to be executed) and CanExecute delegate (code that evaluates if Action is allowed to execute)
CanExecute Predicate<T> returning TRUE if command is allowed to execute. WPF uses this value to enable/disable command buttons.
Execute Action<T> code block that should be executed when command button is clicked. Generally some business function (e.g. save, close, etc.) or application logic (open window, move object, etc.)
ViewModelCommandList (concrete) Contains registered commands for this ViewModel
Add Add(Action,Predicate) – action to execute when command is activated, Predicate – code to check whether or not command should execute. (If null then default AlwaysTrue delegate is create)
Add Add(Action) – action to execute when command is activated. Creates internal AlwaysTrue delegate

Library Class Diagram

Last edited Apr 27, 2011 at 5:23 AM by DrIO, version 4

Comments

No comments yet.