Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Self Evaluating Command for MVVM Pattern

0.00/5 (No votes)
14 Jan 2018 1  
ActionCommand variant that tracks changes of properties and raises CanExecuteChange event on its own.

Introduction

For quite some time, I’ve been using the common ActionCommand implementation that can be found in almost every MVVM library. It works very well in MVVM world, but I didn’t really like all those “RaiseCanExecuteChanged” calls scattered all around my ViewModels code. So I decided to turn things around and make the command responsible for tracking property changes. Hopefully, someone will find this useful.

TLDR: How Do I Use It?

Just instantiate it like a normal ActionCommand, passing Execute and CanExecute callbacks. And register all properties that should be tracked. Do note that properties must be defined on an object implementing INotifyPropertyChange interface.

private SelfEvaluatingActionCommand increaseCounter;

public ICommand IncreaseCounter
{
    get
    {
        if (increaseCounter == null)
        {
            increaseCounter = new SelfEvaluatingActionCommand(OnIncreaseCounter, CanIncreaseCounter)
                .AddPropertyTrigger(() => CounterMax)
                .AddPropertyTrigger(() => Counter);
        }

        return increaseCounter;
    }
}

And you are all set to go. Whenever CounterMax or Counter property changes, command will fire its CanExecuteChange event.

Description and Extendibility

Have a look at the attached file which contains all necessary classes along with a basic sample project.

The core logic lies in PropertyTracker class, which takes care of resolving property names provided via expression and hooking up to property change events of source objects. Internally, it builds a dictionary of source notification objects along with property names registered per given object. Whenever registered property changes, PropertyTracker will invoke an action that was passed to it via constructor.

This way, you can hook up property tracking to your own commands without being restricted by existing inheritance chain. Of course, you can still subclass SelfEvaluatingActionCommand if desired.

When implementing on your own set of commands via composition, be sure to implement ISelfEvaluatingCommand interface. This will let you use those “Fluent” extension methods found in CommandExtensions class.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here