Wiki

Clone wiki

AtomicMVVM / Home

WELCOME TO ATOMICMVVM

The goal of AtomicMVVM is to allow developers to work with MVVM in their XAML based solutions (XPF, Silverlight, Windows Phone, WinRT) with minimal effort while not getting in the way of the code.

INDEX

FEATURE SET

AtomicMVVM supports the following MVVM features:

  • The bootstrapper handles injection of views into a shell, so you don’t have to.
  • The bootstrapper handles joining and creating of views and view models, so you don’t have to.
  • No more commands, just normal methods.
  • No more CanExecute (ICommand again) worries, just normal methods.
  • Can easily link the methods to the properties change notification, so you can update CanExecute or fire off code in a single line!
  • Can pass information from one view to another.

DESIGN

The design goals of AtomicMVVM are (in order): simple over feature rich, unobtrusive over less code and convention over configuration.

SIMPLE OVER FEATURE RICH

AtomicMVVM isn’t going to set the world on fire because rather than build something monolithic that can do everything, in every way we decided to focus on the core of MVVM and build for that. This means it easily slots into projects and the source code also easy to understand:

  • It is a trivial set of files - between two and three depending on the project type.
  • It is less than 300 lines of code per project type. What we trade-off for this is features and options, so it only works one way and if you don’t like that one way there isn’t much you can do about it unless you change the code and because the code is so simple that isn’t hard either! An example of this choice is that we do not support convention binding for controls (like textboxes) to properties. Rather we expect you to just use normal XAML binding, where you get all the powerful features of that without us having to reinvent it.

UNOBTRUSIVE OVER LESS CODE

While other MVVM frameworks allow you to do amazing things by writing TINY amounts of code, a lot of the time you take a penalty for that in the way of having a lot of references, or class inheritance. The moment you are unhappy with something (like having to inherit from a specific class) then you are forced to write massive amounts of code (reinventing the wheel). Rather than model, we have decided to be unobtrusive – for example to convert a normal WPF project to use AtomicMVVM means adding one interface to your Main Window (Shell), implementing a single method, adding one static property to your app class and removing one line of XAML! So you may have a little more setup but in the end it gets out the way easier so you can easily use AtomicMVVM with anything you like.

CONVENTION OVER CONFIGURATION

The final design goal is that there should be as little manual configuration as possible and that if you follow the convention (how we name things) then everything just works. This means the learning curve for you is very shallow, in fact we have only one configuration parameter that is required: What is the name of the shell class and what is the first bit of content to put in it!

ATOMICPHONEMVVM

The original idea behind AtomicMVVM was that it could just work everywhere – but there are places the model we use in AtomicMVVM just doesn’t work. Windows Phone is a key example of that sort of place. In AtomicMVVM we are swopping the content of a frame out all the time, so you are never really leaving a single window, and while this works for Windows Phone – it also breaks a common design goal of the phone: The navigation stack. The navigation stack in Windows Phone is controlled by the frame, so you can think of using AtomicMVVM with Windows Phone as having a frame within a frame and thus we lose navigation to the top most frames. The most obvious side effect of this is the back button on the device no longer works correctly. To solve this we have created AtomicPhoneMVVM, a project that is in many ways similar but in many ways very different. We now do not have a concept of the Views, rather now the pages in the phone application are the Views, and each page is individually responsible for its own binding or put another way, no global boot strapper exists. AtomicPhoneMVVM also has a bunch of features not applicable to AtomicMVVM:

  • IWhenReady – this is an interface you can add to your ViewModel to be notified when the binding is finished – this allows you to update items post binding.
  • Navigate – This method allows the ViewModel to do navigation on the Views (pages).
  • AppBar support – The Windows Phone appbar menu and commands are not based off buttons and thus need special support to work with an MVVM framework.

ATOMICMVVM FEATURES

This section contains information on features found in AtomicMVVM. For the most part these features are available in AtomicPhoneMVVM too.

ATTRIBUTES

REEVALUATEPROPERTY

In the getting started we introduced one attribute, ReevaluateProperty which is used on Can methods, i.e. methods that are prefixed with Can and tell the Command that is created if it can be executed. By adding these attributes to the method it tells the bootstrapper, which properties affect the Can method result. Note: You can have multiple ReevaluateProperty attributes on a method.

TRIGGERPROPERTY

The other attribute is called TriggerProperty and it is used in a similar way to ReevaluateProperty, except it causes the attributed method to fire when the property updates. This is useful for scenarios where one property change causes the value of other properties to change.

[TriggerProperty("SelectedMake")]
public void SetModels()
{
    if (string.IsNullOrWhiteSpace(this.SelectedMake))
    {
        this.Models.Clear();
        return;
    }

    var models = data.Single(_ => _.Name == this.SelectedMake).Data.Select(_ => _.Name);
    UpdateCollection(this.Models, models);
}

An example of this is in the general demo app, in the Car Selector demo, where changing the Make dropdown changes the values of the Model and Colour dropdowns and changing the Model drop down changes the value of the Colour drop down.

Note: It is possible to create an infinite loop, which will result in a stack overflow if the attributed method updates any of the properties that attribute it – so be careful. This attribute may seem not to be a MVVM item and thus violates the first design goal, but this is so easily implemented with the bootstrapper and it is so common that any other way to do this would not be correct.

GLOBAL COMMANDS

The bootstrapper has a property named GlobalCommands which is a List<Tuple<string,Action>>. This list stores a set of global commands that can be used when the view model does not contain a method already. It works on a similar process, the name of the ICommandSource (for example a button) must match the string item of the Tuple, if it does and there is no command in the view model that matches it will run the action item of the Tuple.

Bootstrapper.GlobalCommands.Add("GoToMenu", () => App.Bootstrapper.ChangeView<Menu>());

This is useful where you have a common set of commands that are used in many view models and you do not wish to repeat them in each view model. An example of this is in the general demo app, where most views have a Button that allows you to return to the menu. The Button is always named GoToMenu and no view models have a method like that, so the global command is used rather.

ATOMICSTORAGE

AtomicStorage is a spin off project from AtomicMVVM & AtomicPhoneMVVM, where it aims to make the storage of data easy and simple for systems that have a process lifecycle – in other words it means that suspend/resume issues on Windows Phone and with Windows 8 (Metro) can easily be handled. An example of this can be found in the AtomicPhoneMVVM demo code.

GETTING STARTED

  1. To get started first grab AtomicStorage from Nuget.
  2. For the view class that you want to enable this feature on, change it so it inherits from IDataStore. This interface has no methods that need to be implemented.
  3. Next attribute any properties that you want to store with the Storage attribute and give it a name. Names must be unique.
  4. Chose logical places in your class to do the loading (for example the constructor) and the saving (for example when a property changes). This is done with the LoadSettings and SaveSettings extension methods respectively.
  5. If you are using this with a WinRT application, then you can pass true to those methods to have them store the settings in the roaming cloud profile.
  6. Done & Profit.
public class MainPage : CoreData, IDataStore
{
    [Storage("Name")]
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                _name = value;
                RaisePropertyChanged("Name");
                this.SaveSettings();
            }
        }
    }

    public MainPage()
    {
        this.LoadSettings();
    }

DEMOS

We have created a number of sample applications that make for good starting points when trying to learn AtomicMVVM and it is highly recommended to have a look at those. They can be found within the Demos folder in the source control.

LICENSE

AtomicMVVM is released under a MS-PL License, so that it’s friendly to developers of both open and closed source software.

IN THE WILD

SHAREPOINT HOLIDAY LOADER

POSTAL CODES

KNOWN ISSUES

No known issues! That either means there are none (because we are awesome) or no one has reported any!

Updated