MVVM in C++/CX
(cross-posted from the MSDN UK Team Blog)
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-ViewModel 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.
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. 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.
<local:PhotoViewerPage
x:Class="PhotoViewer.MainView"
...
DataContext="{Binding Source={StaticResource ViewModelLocator}, Path=MainVM}">
MainViewModel^ ViewModelLocator::MainVM::get()
{
if (nullptr == m_mainViewModel)
{
m_mainViewModel = ref new MainViewModel();
}
return m_mainViewModel;
}
<GridView ...
ItemsSource="{Binding Photos}"
... >
[Windows::UI::Xaml::Data::Bindable]
[Windows::Foundation::Metadata::WebHostHiddenAttribute]
public ref class MainViewModel sealed : public ViewModelBase
{
...
}
public ref class ViewModelBase : public Common::BindableBase
{
...
}
ImageSource^ PhotoViewModel::Photo::get()
{
if (nullptr == m_photo)
{
...
OnPropertyChanged("Photo");
...
}
return m_photo;
}