mobile menu icon

Windows apps development best practices

Published by Carlos Blé on 24/02/2016

Windows Apps, C#, .Net


I don’t really know whether they are the best practices to be honest, and certainly there is a lot for me to learn but these are principles and practices that work well for us in the development of a complex native Windows App (Windows 8.1+) using C# and the MVVM pattern.

Files in my example (namespace + classname) :

Page navigation is performed by the framework:

The first parameter is the type of the target Page and the second is an “object” intended to send any custom parameter. Such parameter is received as an argument of OnNavigatedTo method in the target page.

The code above is used to navigate from App.xaml.cs (Main page) to Vehicle (Page).

The NavigationService is an indirection level that sends the ViewModel to the View as the context object. It’s used pretty much like Frame.Navigate:

Implementation (NavigationService.cs):

This is how the view model is received in Vehicle’s codebehind (Vehicle.xaml.cs):

Principles applied in the code snippet above:

Avoid global statics: Although there is a single instance of AppState class - is a global singleton, we inject it into every view model that requires read or write access rather than having direct static references. The Factory knows the AppState singleton and injects it to the viewmodels. Although two different views may require the same data, we try not to store everything in the AppState but rather cache the service methods retrieving the required data and then injecting the same instance service to both viewmodels. The amount of data kept in the AppState should be minimal, basically it should contain identifiers that view models understand in order to pull data from the services. Sometimes it contains more data to avoid time consuming transformations or calculations, that’s fine, it’s a trade off.

Custom controls: We ended up having our own custom pages, inheriting the Page control to remove duplication from initialization process. One of such inheritors is generic: _CachedPage_, where T is the type of ViewModel. However in xaml you can't define a page inheriting from a generic class. To work around this minor issue we create an intermediate empty class:

Then in xaml we can set the type of our page to be CachedVehiclePage.

Nested user controls: When a Page contains a user control, the DataContext of that user control is the same than the Page’s one. Neither the codebehind or the xaml of user control should overwrite the DataContext. The DataContext should not be set programmatically it’s just inherited from the parent container. Otherwise there could be race conditions and memory leaks.

Data binding: We don’t bind domain models directly to the GUI. The main reason is that double way binding requires public setters. Sometimes we create a bindable object that wraps the domain model exposing only ome properties. But we often create custom bindable objects from the domain model for the specific purposes of the view.

I’ll update this post with more stuff that is working well for us.

Originally published in Carlos Blé's blog.

Volver a posts