MSDN UK Team blog

Get all the latest Microsoft developer news, tools, downloads, tutorials and tips right here, every day.
Search Form
Unfiltered HTML
Developers code with microsoft

Guest Post: MVVM in C++/CX

Unfiltered HTML
Unfiltered HTML

Guest Post: MVVM in C++/CX

  • Comments 3

clip_image004David Britch is a Senior Technologist at Content Master, and for the past year has been working on a number of projects with the patterns & practices group at Microsoft. David has authored and contributed to a range of recent software development publications including books, guidance documentation, whitepapers, videos, HOLs, and ILT courses. David has a PhD in Computation, specializing in image and signal processing.

Previously I’ve written about the power of C++/CX for developing Windows Store applications. C++ is the language for power and performance on WinRT, and the combination of C++11 and C++/CX makes C++/CX read a lot like C#, while giving you the benefits of native code. In addition, the ability to develop the UI using XAML enables the designer-developed workflow present in the .NET world.

The MVVM pattern lends itself naturally to XAML application platforms, including C++/CX. This is because it leverages some of the specific capabilities of XAML, such as data binding and commands. While managed code developers are well-versed in the MVVM pattern, C++ developers typically are not. Therefore, the purpose of this article is to demonstrate how to implement MVVM in C++/CX. However, before I get into the details of implementing MVVM in C++/CX, I’ll first provide a quick overview of MVVM.

The MVVM Pattern

The Model-View-View Model pattern can be used on all XAML platforms. Its intent is to provide a clean separation of concerns between the user interface controls and their logic. There are three core components in the MVVM pattern: the model, the view, and the view model:

· The view is responsible for defining the structure, layout, and appearance of what the user sees on the screen. Ideally, the view is defined purely with XAML, with a limited code-behind that does not contain business logic.

· The model in MVVM is an implementation of the application's domain model that includes a data model along with business and validation logic.

· The view model acts as an intermediary between the view and the model, and is responsible for handling the view logic. Typically, the view model interacts with the model by invoking methods in the model classes. The view model then provides data from the model in a form that the view can easily use.

The following illustration shows the relationships between the three components.

clip_image002

The main benefits that MVVM provides include a separation of concerns, enabling the developer-designer workflow, and increasing application testability. For more information about MVVM, see Developing a Windows Phone Application using the MVVM Pattern, Implementing the MVVM Pattern, and Advanced MVVM Scenarios.

Implementing MVVM in C++/CX

In order to demonstrate implementing MVVM in C++/CX I’ve written a small photo viewing sample app, which can be downloaded here[DJB1] . In the app, there are two pages. The first page presents a thumbnail gallery view of photos in the users Pictures library. Clicking on a thumbnail takes the user to the second page which displays the full image.

Each page in the app is implemented as a view, with each view having a corresponding view model class. Both view models share the same model class.

The app needs to connect its views to its view models, and it does this by using a view model locator. The ViewModelLocator class has properties that retrieve a view model object for each page of the app, which the view model object being assigned to the DataContext of the page that represents the view.

MainView.xaml

<local:PhotoViewerPage

x:Class="PhotoViewer.MainView"

...

DataContext="{Binding Source={StaticResource ViewModelLocator}, Path=MainVM}">

The ViewModelLocator static resource is declared in App.xaml. The MainVM property, in the ViewModelLocator class, simply returns an instance of the MainViewModel class.

ViewModelLocator.cpp

MainViewModel^ ViewModelLocator::MainVM::get()

{

if (nullptr == m_mainViewModel)

{

m_mainViewModel = ref new MainViewModel();

}

return m_mainViewModel;

}

Controls in the view can then bind to objects in the view model.

MainView.xaml

<GridView ...

ItemsSource="{Binding Photos}"

...>

The code above shows a GridView control binding to the Photos property in the instance of the MainViewModel class.

For a view model to participate in data binding with the view, it must have the Windows::UI::Xaml::Data::Bindable attribute to ensure that the type is included in XAML’s generated file.

MainViewModel.h

[Windows::UI::Xaml::Data::Bindable]

[Windows::Foundation::Metadata::WebHostHiddenAttribute]

public ref class MainViewModel sealed : public ViewModelBase

{

...

}

In addition, you need to include the header for your view model in the App.xaml.h header file, either indirectly or directly. This ensures that the types necessary to work with XAML are generated at compile time. In the sample app, all view model header files are included in the ViewModelLocator.h file, which is included in App.xaml.h.

View models that need to notify views that a property value has changed must raise the PropertyChanged event. To do this, view model classes need to implement the INotifyPropertyChanged interface. Visual Studio provides an implementation of the INotifyPropertyChanged interface in the BindableBase template class that you can use as a base class for any XAML data source. Therefore, view model classes can inherit the INotifyPropertyChanged implementation by deriving from the BindableBase class. In the sample app, the ViewModelBase class derives from the BindableBase class.

ViewModelBase.h

public ref class ViewModelBase : public Common::BindableBase

{

...

}

Whenever view models need to tell the UI that a bound property has changed, they call the OnPropertyChanged method that they inherited from the BindableBase class.

PhotoViewModel.cpp

ImageSource^ PhotoViewModel::Photo::get()

{

if (nullptr == m_photo)

{

...

OnPropertyChanged("Photo");

...

}

return m_photo;

}

In addition, you can also use data binding for UI controls that cause the app to perform operations. If the control derives from ButtonBase, the control’s Command property can be databound to an ICommand property on the view model. When the control’s command is invoked, the code in the view model is executed. For more information, see the Hilo project.

Summary

C++/CX apps can use XAML for the UI, enabling C++/CX developers to use the MVVM pattern in an app to make the app easier to test, maintain, and evolve. The accompanying sample app enables a user to view a gallery of thumbnails of photos in their Pictures library, and view a selected image full size. The app follows the MVVM pattern of UI controls on the view binding to objects on the view model.

Download

 

Bookmark

  • Thanks for this post. There are very few articles about C++/CX guidelines.

    I've looked at the code and noticed that your whole app is in C++/CX. Even the model classes are ref classes, and are even using only Platform types.

    I've written myself a few C++/CX code, and I also end up with the same problem: the whole app MUST be in C++/CX.

    Herb Sutter claims that C++/CX should only be used as a thin boundary in a C++/CX program, and the main app code should be standard C++.

    Unfortunately, I don't know how to use C++/CX in an app as a thin boundary. One reason for that is a winrt class public method cannot have standard C++ parameters. Only winrt-compatible parameters are accepted. Winrt classes cannot use standard C++ objects. So, all the classes in the app must be winrt classes. I don't know how to use standard C++ code in a C++ app. This is a real problem for me.

    Do you know how to achive this? For example, could your model classes in photos.cpp be standard C++ classes?

  • If you are interested in doing MVVM in C++/CX I recommend checking out StyleMVVM. It contains a full blown Dependency Injection Container, ViewModel location, and most things needed to do proper MVVM development (implementation of ICommand, Attached Command behaviors, and other things like ITileService and more)

    Note: I'm biased because I happen to write it ;)

  • I'm using a C book but the code just gives me errors ?

Page 1 of 1 (3 items)
Leave a Comment
  • Please add 5 and 3 and type the answer here:
  • Post