ImaginationOverflow

The knowings and experiences of a group of developers.

My Vandalized View of Mvvm – Lets code

In the last post I gave an overall view into the MVVM pattern, in this I will put my hands to work and give some examples on what I meant.

In the last post I refereed that the MVVM pattern have three main layers, the view, view model and model. When you are coding to Windows Phone 7 (or WPF in general) the view layer is divided in two parts:

  • The Xaml, the actual user interface.
  • The code behind, code that is associated to behaviors or events of the user interface.

The xaml is just xml, used to define the UI, here is an example:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  <Button Content="GetBytes"  Name="GetBytesButton"  />
  <TextBlock Name="textBlock1" Text="TextBlock"  />
</Grid>

The other MVVM layers have no special treatment in the WP7 framework, they’re just normal classes. One fancy thing that the WP7 framework has is “Binding”. This feature allows you to make code that is aware on other properties state. This feature is interesting because it have a direct support in xaml, as shown on the following snippet:

<TextBlock Name="textBlock1" Text="{Binding SomeTextProperty}" />

As you saw the Text property is now Binded to the “SomeTextProperty” this means that the property Text will change when the property “SomeTextProperty” changes.

If you use this features in a right way you can make your business logic completely non view aware, making that code reusable.

To explain the direct implementation of MVVM in WP7 I will use an example that consist in a very simple UI that with one button and a textblock. When the button is pressed a web request will be made and the number of bytes returned from it will be showed on the textblock.


<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  <Button Content="GetBytes" Height="72" HorizontalAlignment="Left"
    Margin="153,211,0,0" Name="GetBytesButton" VerticalAlignment="Top"
    Width="160" Click="GetBytesButtonClick"/>

  <TextBlock Height="43" FontSize="30" HorizontalAlignment="Left"
    Margin="171,79,0,0" Name="textBlock1" Text="{Binding ByteCount}"
    VerticalAlignment="Top" Width="130" />
</Grid>

Notice that the Text property is binded to the value of ByteCount, but where is that property defined? Check out the UI code behind:

public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public int _byteCount;
    public int ByteCount
    {
      get { return _byteCount; }
      set
      {
         if (_byteCount == value)
           return;
         _byteCount = value;
         if (PropertyChanged != null)
           PropertyChanged(this, new PropertyChangedEventArgs("ByteCount"));
      }
    }

    // Constructor
    public MainPage()
    {
       InitializeComponent();
       this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
       DataContext = this;
    }
   (...)
}

Note the following:

  • The implementation of the interface INotifyPropertyChanged.
  • The definition of the ByteCount property.
  • The set on the DataContext property.

First things first, the INotifyPropertyChanged declares just one member, an event:

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}

That event is the backbone of the binding system used on the WPF, consider the given example, the textblock property Text is binded to ByteCount, that means that the WPF runtime will register a handler on the MainPage event. When the event is raised with the right PropertyChangedEventArgs (meaning that the property name is ByteCount) the textblock Text property will be updated. The handler registered by the WPF runtime probably looks something like the following:

mainPageInstance.PropertyChanged += (s, args) =>
{
    if(args.PropertyName == "ByteCount")
        SetTextPropertyIntoTheTextBlock(GetContextProperty("ByteCount"));
};

After understanding the purpose of INotifyPropertyChanged interface, understanding the implementation of ByteCount should be straight forward. The set raises the INotifyPropertyChanged event when a new value is setted on the property, notifying all its possible candidates, in this case the textblock.

The DataContext property tells the WPF where should it go find the properties binded in the xaml code, when you make a bind like {Binding SomeProp} you can think that you are making {Binding DataContext.SomeProp}, meaning that the WPF will at runtime do the following:

  • Search in the DataContext for properties with the name that you put in the binds and try to assign their value into the UI elements that you selected.
  • Try to register handlers into the PropertyChanged event so that the UI elements can be updated.

Note that you can bind any property, the raise of the PropertyChanged event is only needed on volatile variables.

After the UI part explained let’s go to the implementation of the Click event, if you should notice the Click property in the Button command, showed in the previous xaml snippet.

private void GetBytesButtonClick(object sender, RoutedEventArgs e)
{
    var request = WebRequest.CreateHttp("http://www.google.com");
    request.BeginGetResponse(ar =>
    {
      var response = request.EndGetResponse(ar);
      var count =
              new StreamReader(response.GetResponseStream()).ReadToEnd().Length;
              Dispatcher.BeginInvoke(() =>
                {
                   ByteCount = count;
                });
              }, null);

}

The implementation is pretty easy to understand, if you have made code to windows phone the asynchronous request isn’t a surprise, if you haven’t, now you know that any function/method that can be heavy to the system (like making a web request) only have an asynchronous interface.

Another strange thing in the snippet above is the Dispatcher.BeginInvoke call, this must be done because of the strategy used in WPF for assuring non concurrent access while changing UI elements, you call search for thread confinement, I recommend this blog post. If you worked with WinForms, this is the same as post to the SynchronizationContext, for swing developers the same of SwingUtilities.invokeLater.

You are probably asking where is the MVVM in all of this? The code is all in the UI code behind and no real separation between UI and business logic. I had to made the post like this so that you could understand a little bit of the WP7 programming environment and interface, so let the separation begin.

Clearly we have three diferent components embedded into one:

  • The service that knows how to make web request and count the bytes returned – Model.
  • The UI layout and logic – View.
  • The data presented by the UI (ByteCount) – View Model.
The following class diagram shows the implementation of the Model and the View Model:

The Model consists in a simple service that given an uri it returns the byte count of the response, the code inside is just like the one shown in the button click handler. The interface is just common sense on creating abstraction and useful for my next blog post.

The fun fact in the diagram is the implementation of the ViewModel, the INotifyPropertyChanged interface implementation should be easy to understand since the reason to do is the same explained in the example given above.

The property Instance is just a singleton to the MainViewModel, the ByteCount implementation is the same as the shown above. And here is the rest of the View Model implementation:

//ByteCount Implementation
(...)
public ICommand FetchGoogleHttpResponseByteCountCommand { get; private set; }

public static MainViewModel Instance { get; private set; }

static MainViewModel()
{
    Instance = new MainViewModel(new SimpleWebRequestResultCounter());
}

public MainViewModel(IWebRequestResultCounter counterService)
{
    _counterService = counterService;
    FetchGoogleHttpResponseByteCountCommand = new SimpleCommand(() => _counterService.GetCountFor
    (
      new Uri("http://www.google.com",UriKind.Absolute),
         count => Deployment.Current.Dispatcher.BeginInvoke(() => ByteCount = count))
    );
}

Probably the strangest thing where is the ICommand, where is the interface declaration:

public interface ICommand
{
    event EventHandler CanExecuteChanged;
    bool CanExecute(object parameter);
    void Execute(object parameter);
}

An ICommand is just an Action with some add-ons. First it has a method for checking if it can execute given a parameter, this is useful for instance to assert preconditions before running the command, and receiving the parameter that will be passed to the execute method enlarge the preconditions possibilities. The most interesting feature is the event declaration. You probably figure it out yet, but yes you can bind directly on the xaml events to commands! I will talk about this in my next post but if you can’t wait any longer check this blog post.

In the MainViewModel constructor I’m setting the FetchGoogleHttpResponseByteCountCommand with the behavior that I would like it to have, in this case it means to call the service passed on the constructor and save the service response into the bindable property ByteCount.
Once again the variable affectation must be done in the UI thread because the property set will call the handlers registered by the WPF.

Finally the View code behind:

public partial class MainPage : PhoneApplicationPage
{
  private MainViewModel _viewModel;

  public MainPage()
  {
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);

  }

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
DataContext = _viewModel = MainViewModel.Instance;
}

private void GetBytesButtonClick(object sender, RoutedEventArgs e)
{
_viewModel.FetchGoogleHttpResponseByteCountCommand.Execute(null);
}
}

It’s pretty much the same the only difference is that there is no non-UI code.

With this post I hope that people understand the basic WP7 environment and how some of the core parts work. The MVVM basics are all here and there isn’t much more to talk about. Despite the simplicity the separation of all the different layers present in this pattern are clear. In the next blog post I will talk about the MVVM Light and integration with the WPF environment, how to abstract from the Dispatcher and event to command bindings.

Until then you can check out this project on github and comments are welcome.

Advertisements

4 responses to “My Vandalized View of Mvvm – Lets code

  1. lbugnion March 20, 2012 at 1:18 pm

    Hi,

    Not sure if this is a translation issue or what, but XAML is not “pseudo-XML”. It is following the rules of XML (where the X stands for eXtensible). If you parse XAML in an XML parser, you won’t get errors (which is one of the major advantages of XAML over HTML).

    Cheers,
    Laurent

  2. DVD March 20, 2012 at 1:31 pm

    @lbugnion
    My point in there was, this is xml, but you can use it to make some cool stuff aka binding, regards of who or what supports that.
    But I agree with you, I shouldn’t mess stuff around. Thanks for the heads up.
    I edited the post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: