Alain Hufkens {Rich Interactive Applications Developer}

9Feb/100

Model-View-ViewModel in Silverlight and Flex

Last year I have been working a lot on Flex applications, and because of this I usually take my experience from Flex development and apply it to Silverlight. One example is the PureMVC framework that we use at Nascom for most RIA applications we build. The framework also has ports towards other technologies and one of these is the C# Silverlight port. I recently checked it out but they seem to have trouble keeping up with the speed of Microsoft's Silverlight releases.

So let's see if I can bring some of the patterns I learned while developing Silverlight into the world of Flex. One specific pattern that I want to talk about is the Model-View-ViewModel pattern. It's a specialization of the PresentationModel design pattern introduced by Martin Fowler specific for the Windows Presentation Foundation (WPF). Yeah, but what about the MVC pattern? Doesn't that already cover all our problems? In the MVC pattern, the model is the data, the view is the user interface, and the controller is the programmatic interface between the view, the model, and the user input. This pattern, however, does not seem to work well in declarative user interfaces like Windows Presentation Foundation (WPF) or Silverlight because the XAML that these technologies use can define some of the interface between the input and the view (because data binding, triggers, and states can be declared in XAML). And for the same reason it also applies to Flex, and even more to Flex4 because MXML will become more declarative in the future.

So what is the Model-View-ViewModel? The pattern is an adaptation of the MVC pattern in which the view model provides a data model and behavior to the view but allows the view to declaratively bind to the view model. The view becomes a mix of XAML and C#, the model represents the data available to the application, and the view model prepares the model in order to bind it to the view.

Probably most Silverlight developers out there are already familiar with this pattern, but I created two small sample applications (one in Silverlight 3 and one in Flex4 beta 2) to compare both technologies and give you an idea how it works. Both applications do exactly the same thing. They load an XML file with data (Phones) and display this data using data binding. You can change the amount so that you can see the total price changing. Yeah, this is definitely no rocket-science (doh, should have used rockets!) , but it works. The Silverlight client loads the XML file using LINQ. LINQ is pretty cool and powerful, but it still takes more code to parse an XML file in Silverlight than it does in Flex using e4x.

You can download the source files for the Silverlight 3 and Flex4 demos here.

Model-View-ViewModel in Silverlight 3

Install Microsoft Silverlight

Model-View-ViewModel in Flex 4 (right click to view source)

What do you think? I find this pattern easy to use in applications that depend heavily on data binding like Silverlight and maybe also Flex. But I think I will still be using PureMVC for my next big Flex Project.

Filed under: flex, silverlight No Comments
1Jun/090

Flex 4: DataGroup and ItemRenderers

fbbuilderToday the beta's of Flash Catalyst and Flash Builder became available for download on Adobe Labs. This means that we can now start to play with the new Flex 4 SDK. There has been some controversy lateley about the pro's and cons of Flex namespaces. I was in the pro camp as you can see in this post I made some time ago. But enough about this discussion ;)

If you want to have more information about the new Flex 4 SDK and what has changed you can go to the following articles:

For my first blog post about Flex 4 I want to show you one of the new components, and that's the spark.components.DataGroup component. Why? Because I have been using the old mx.core.Repeater a lot and there is no repeater in the new spark components.

In the old days of Flex 3 you could use the Repeater class when you needed a very specific view for customizing a list of data. It would look something like this:

<mx:VBox>
    <mx:Repeater id="myRepeater">
        <mx:dataProvider>
            <local:Person firstName="Alain" lastName="Hufkens"/>
            <local:Person firstName="Hugh" lastName="Hefner"/>
            <local:Person firstName="Jimi" lastName="Hendrix"/>
        </mx:dataProvider>
        <mx:HBox>
            <mx:Label text="{myRepeater.currentItem.firstName}"/>
            <mx:Label text="{myRepeater.currentItem.lastName}"/>
        </mx:HBox>
    </mx:Repeater>
</mx:VBox>

This example here is pretty simple, but it gives you a list that displays the persons showing the first and last name. You could extend this with the person's photo or address.

With the new DataGroup component you need a different approach and you need to work with ItemRenderers, something that already existed in the Flex 3 SDK. The next code snippets show you how to do this:

The first example uses the spark.skins.default.DefaultItemRenderer that can be used for very simple lists. By default the list outputs the toString() of an Object or in this example shows the String from the DataProvider.

<s:DataGroup itemRenderer="spark.skins.default.DefaultItemRenderer">
    <s:layout>
        <s:VerticalLayout gap="1" />
    </s:layout>
    <s:dataProvider>
        <s:ArrayCollection>
            <fx:String>Frog</fx:String>
            <fx:String>Cat</fx:String>
            <fx:String>Mouse</fx:String>
        </s:ArrayCollection>
    </s:dataProvider>
</s:DataGroup>

The next example uses the spark.skins.default.DefaultComplexItemRenderer. This ItemRenderer renders different Graphical and complex components. You can have a Component like a Button, DropDownList, ... next to a graphical object like a Rect, Ellipse, ... next to each other.

<fx:Declarations>
    <s:SolidColor id="fillColor" color="#fff000"/>
</fx:Declarations>

<s:DataGroup itemRenderer="spark.skins.default.DefaultComplexItemRenderer">
    <s:layout>
        <s:HorizontalLayout/>
    </s:layout>
    <s:dataProvider>
        <s:ArrayCollection>
            <s:Button label="Button" />
            <s:Rect fill="{fillColor}" width="20" height="20"/>
            <s:Ellipse fill="{fillColor}" width="20" height="20"/>
            <s:DropDownList />
        </s:ArrayCollection>
    </s:dataProvider>
</s:DataGroup>

That's all pretty cool but it's not what I needed. I just needed something that can present my Person object. So in this case we need to create a Custom ItemRenderer. This is a very easy thing to do and the end result is a lot better then the Repeater solution.

<s:DataGroup itemRenderer="PersonItemRenderer">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    <s:dataProvider>
        <s:ArrayCollection>
            <local:Person firstName="Alain" lastName="Hufkens"/>
            <local:Person firstName="Hugh" lastName="Hefner"/>
            <local:Person firstName="Jimi" lastName="Hendrix"/>
        </s:ArrayCollection>
    </s:dataProvider>
</s:DataGroup>

And this is the code for the PersonItemRenderer:

<s:ItemRenderer
 xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:s="library://ns.adobe.com/flex/spark"
 xmlns:mx="library://ns.adobe.com/flex/halo">
 
  <fx:Declarations>
  <s:SolidColor id="normalColor" color="#000000"/>
  <s:SolidColor id="hoveredColor" color="#FF0000"/>
  </fx:Declarations>
 
  <s:states>
    <s:State name="normal"/>
    <s:State name="hovered"/>
  </s:states>
 
  <s:layout>
    <s:HorizontalLayout/>
  </s:layout>
 
  <s:Ellipse fill="{normalColor}" fill.hovered="{hoveredColor}"
      width="10" height="10" />
  <s:SimpleText text="{data.firstName} {data.lastName}"
      color.hovered="#FF0000"/>
 
</s:ItemRenderer>

You can see the demo (including source) here.

Filed under: flex No Comments