Cross-Training in Silverlight & Flex–MVVM vs Presentation Model

More Cross-Training in SIlverlight and Flex

Shout it

This is probably my favorite topic in this Silverlight/Flex series.  In the Silverlight world, I have written extensively about the MVVM (Model-View-ViewModel) – a separated presentation pattern for stateful clients (like Rich Internet Applications).  When I got into Flex, I was shocked to find out how easy the pattern was to implement.  Developers in the Microsoft space call it MVVM but it was coined by Martin Fowler many years previous as Presentation Model.  I will use these terms interchangeably but mostly refer to MVVM when explaining the SIlverlight story and Presentation Model when explaining the Flex story.

If you do a Google search today for “MVVM and Flex”, the first post is by somebody who claims that MVVM is not a good fit for Flex.  I couldn’t disagree more.  Out of the box, the Flex framework makes it much easier to implement a Presentation Model than similar MVVM implementations in Silverlight.  That is not to say that there aren’t good third-party libraries that make it easier in Silverlight, but without any help, it is easier to do in Flex. 

I will show some examples and they should speak for themselves.

MVVM in Silverlight

In the MVVM pattern, there are two particular interfaces that are interesting to know:

  • INotifyPropertyChanged – an interface that lets ViewModels notify the UI when a property changes
  • ICommand – an interface that allows the UI to execute code on the ViewModels

Lets say we have a simple application where the model is excluded because it is not relevant to what I am trying to show.  The behavior is simple: when the user presses a button, read the text in the input field and output “Hello <input>”.  A simple implementation of the view might look like this:

<UserControl.Resources>
    <local:ViewModel x:Key="ViewModel" />
</UserControl.Resources>

<Border BorderThickness="5" CornerRadius="5" DataContext="{StaticResource ViewModel}"
        BorderBrush="Black" Height="Auto" Width="Auto">
    <StackPanel Orientation="Horizontal">
        <TextBox Width="100" Margin="3" Text="{Binding Input, Mode=TwoWay}" />
        <Button Content="Say Hello" Margin="3" Command="{Binding SayHelloCommand}" />
        <TextBlock Margin="3" VerticalAlignment="Bottom" Text="{Binding Output}" />
    </StackPanel>
</Border>

The ViewModel to support that logic looks like this:

public class ViewModel : INotifyPropertyChanged
{
    public string Input { get; set; }

    private string _output = string.Empty;
    public string Output
    {
        get { return _output; }
        set
        {
            if (_output == value)
                return;

            _output = value;
            RaisePropertyChanged("Output");
        }
    }

    public ICommand SayHelloCommand { get; private set; }

    public ViewModel()
    {
        SayHelloCommand = new DelegateCommand(SayHello);
    }

    private void SayHello()
    {
        Output = "Hello, " + Input;
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        var handlers = PropertyChanged;
        if(handlers != null)
            handlers(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class DelegateCommand : ICommand
{
    private readonly Action action;

    public DelegateCommand(Action action)
    {
        this.action = action;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        action();
    }

    public event EventHandler CanExecuteChanged;
}

This example, admittedly, is a bit hyperbolic.  It includes everything you need to write a ViewModel from scratch.  In reality, the DelegateCommand is written once and reused.  In addition, most people will at least abstract the RaisePropertyChanged and PropertyChanged code by moveing it to a ViewModelBase class.  On that note, there are several third-party frameworks for making MVVM more pleasant in Silverlight.  I wrote one of those helpers, called ViewModelSupport.  Using the powerful, somewhat magical base class, the previous code can be re-written as:

public class ViewModel : ViewModelBase
{
    public string Input
    {
        get { return Get<string>("Input"); }
        set { Set("Input", value); }
    }

    public string Output
    {
        get { return Get<string>("Output"); }
        set { Set("Output", value); }
    }

    public void Execute_SayHelloCommand(object param)
    {
        Output = "Hello, " + Input;
    }
}

The latter is certainly better than the former, but my point is that there is a lot of ceremony and plumbing involved in order to get Silverlight applications wedged into the MVVM pattern.  Please don’t misunderstand me: MVVM is usually the best pattern for developing separated Silverlight applications.  I am only suggesting that there is a lot of ceremony.

In addition to my ViewModelSupport package, there are several other libraries out there that help you write implement MVVM in Silverlight including:

Presentation Model in Flex

In Flex, the binding system is very different than the way Silverlight does it.  Notifications are similar to INotifyPropertyChanged in Silverlight, but there is no interface specifically for property changes.  Instead, there is just an event that gets fired called “<property>Changed” where <property> is the name of the property that changed.  It is also simplified in that you can decorate your class or individual properties with [Bindable] and the Flex compiler writes all of your notification code for you.  As far as executing code in the Presentation Model, there is no ICommand like in Silverlight – the view simply calls into the Presentation Model directly. 

Lets say we have a simple application where the model is excluded because it is not relevant to what I am trying to show.  The behavior is simple: when the user presses a button, read the text in the input field and output “Hello <input>”.  A simple implementation of the view might look like this:

<fx:Script>
        <![CDATA[
            var pm:PresentationModel = new PresentationModel();
        ]]>
</fx:Script> 

<s:BorderContainer borderWeight="5" cornerRadius="5"
                   borderColor="black" minHeight="0" width="100%">
    <s:HGroup left="3" right="3" top="3" bottom="3">
        <s:TextInput width="100" text="@{pm.input}"/>
        <s:Button label="Say Hello" left="6" click="pm.sayHello()" />
        <s:Label left="6" verticalAlign="bottom" height="100%" text="{pm.output}">
    </s:HGroup>
</s:BorderContainer>

The Presentation Model then looks like this:

[Bindable]
public class PresentationModel
{
    public var input:String;
    public var output:String;

    public function sayHello():void {
        output = "Hello, " + input;
    }
}

That’s it!  The [Bindable] flag tells the input and output properties to send inputChanged and outputChanged events automatically.  The sayHello function gets called directly from the view without the need to hook up a command.  It is really that easy to implement Presentation Models in Flex.

Much like the Silverlight side, there are frameworks that will help you along the way.  Because the binding system is as strong as it is in Flex (more details in a future post), you don’t need much to implement Presentation Models.  At a very minimum, though, I recommend using an Inversion of Control framework like flex-ioc, robotlegs or Swiz

Tags: , , ,

12 Responses to “Cross-Training in Silverlight & Flex–MVVM vs Presentation Model”

  1. Silverlight vs Flex – MVVM vs Presentation Model…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. [...] This post was mentioned on Twitter by Brian Genisio, Brian Genisio. Brian Genisio said: Blogged: Cross-Training in Silverlight and Flex — MVVM vs Presentation Model — http://j.mp/dPLIIE [...]

  3. [...] where you declaratively state that a property in the view is “bound” to data in your model (or presentation behavior layer).  This means that when the model data changes, the UI is updated.  Conversely, when a [...]

  4. [...] declaratively state that a property in the view is “bound” to data in your model (or presentation behavior layer). This means that when the model data changes, the UI is updated. Conversely, when a user sets [...]

  5. [...] 11:15p Surfed around for flex mvvm. 1st to popup was an argument against: Binary Bob’s Blog » Why MVVM does not fit with Flex And here’s one for: Cross-Training in Silverlight & Flex–MVVM vs Presentation Model « Brian Genisio’s House… [...]

  6. [...] for Flex. Comparing a canonical MVVM example in Silverlight with the same example in Flex highlights how well Flex works with the Presentation Model pattern. The data binding story in Flex (both in [...]

  7. [...] 11:15p Surfed around for keywords flex and mvvm. 1st to popup was an argument against: Binary Bob’s Blog » Why MVVM does not fit with Flex And here’s one for: Cross-Training in Silverlight & Flex–MVVM vs Presentation Model « Brian Genisio’s House… [...]

  1. Mike Ward says:

    Brian,

    The Silverlight part of this article is one of the best and most concise presentations of MVVM I’ve seen. Nice work. Also, good reminder about your ViewModelBase work. I was noodling around with WPF the other day and looking for an MVVM. Totally forgot you wrote one. See you at Codemash.

    - Mike

  2. ali says:

    hi brain,
    it’s good,clean post.Now i have a scenario in which i want to save the user data on button click.
    registration form just 4 fields.

    firstname txtfirstname

    lastname txtlastname

    email txtemail

    telephone txtphone

    and one save button

    Now i set the command property in the ui page is “SaveCommand” and in the view model i
    made SaveCommand Property.Now how on save button the above four text boxes values can i get in the view model so that i can insert into the database.And i think there is property CommandParameter how i set the four text boxes in the commandparamete and
    get receive on viewmodel.

    Can u help me wht type of code is in the view model so that i can proceed my proof of concept a stuck me for two days.

    ur help can be very helpfull for me.

    Thnx in advance.

  3. Brian,

    I am really enjoying this series. You’ve opted to keep it simple and concise, and I applaud you.

    One thing I think you’ve neglected to mention here however is the fact that Silverlight encourages you to use a ViewModel, through the requirement of setting a DataContext. As you know, Flex has no such requirements, and it is trivial to bring in multiple models/handlers/whatever into the one view. In fact, you don’t just bind properties, you can bind in whatever you like. As such, there is a lot more flexibility in how you architect your solution. It’s funny to me, having come this from the other direction to you (from Flex to Silverlight), I initially found myself wondering why there was so little deliberation amongst the Silverlight community about micro-architectures.

    Justin

  4. admin says:

    @Justin:

    Though I agree that the data binding story in Flex is more flexible, I don’t agree that Silverlight is as deficient as you suggest. Sure, they use DataContexts as the default binding source for the property bindings, but that is really just a convenience. It doesn’t preclude you from binding properties to other data sources.

    For instance, you might have a ListBox where the data context is one thing, but the items source is another:

    <UserControl.Resources>
       <local:MyClass1 x:Key=”thing1″/>
       <local:MyClass2 x:Key=”thing2″/>
    </UserControl.Resources>

    <ListBox DataContext=”{Binding {StaticResource thing}}” SelectedItem=”{Binding PropertyOnThing1, Mode=TwoWay}” ItemsSource=”{Binding PropertyOnThing2, Source={StaticResource thing2}}” />

    As you can see, you aren’t relegated to a single data context. I still prefer the less declarative but more flexible approach that Flex uses, though. It is generally less verbose.

    As far as “Micro-architectures”, there are several: Magellan, Caliburn Micro, MVVM Light, and Prism are a few that jump into my brain right now. Many more exist.

    Brian

Leave a Reply