MVVM, Orientation & Idioms

MVVM, Orientation & Idioms

My background in C#, WPF, and UI development means I am a real proponent of MVVM. Not a ‘You must not have any code-behind’ fanatic, but where it makes for a more testable and structured development I will strive for behavioural code in the ViewModel, UI definition/behaviour in the View.

One significant difference between developing with WPF on Windows and Xamarin Forms, is that with Windows, on the whole, you are not bothered about screen size & orientation. In theory, maybe you should, but on the whole you can assume that one layout will suffice.

With Xamarin Forms you are targeting multiple platforms, screen sizes, resolutions & orientations. And so you need a mechanism for changing layout depending on these parameters change, and note: Orientation changes dynamically.

Was thinking about this in the context of MVVM. TheDevice (Idiom), screen size and orientation are definitely the purview of the View and not the ViewModel. But I do not want lots of Code Behind in the View detecting screen sizes, changes to orientation etc, and then dynamically changing layout. So how to manage?

My initial thought was to have a view for each Idiom & Orientation. (Basically choose a set of Screen Sizes (I decided three was reasonable) and then design a layout for each size with two orientation. In effect meaning six screen designs for every Logical view. A lot of work, but it keeps everything compartmentalised, which I like.

How would this work in practice:

  1. Detect the screen size at start up.
  2. Set the Main Screen to the desired View (Content Page)
  3. Set the BindingContext.
  4. Detect any change in Screen size (i.e. Change to Orientation)
  5. Replace Content of MainPage with Content of desired View
  6. Reset Binding Context.

Well this nearly worked, but not quite. Two issues:

  1. Binding Context for the items in the Content were not re-set. This wasn’t too much of a problem. Just meant setting up the Binding Context on each view to the same ViewModel. Bit of a hack, but as long as you maintain one ViewModel per logical View then this would work
  2. ‘Null Exceptions’ from Xamarin Forms and other third party libraries were thrown after successive re-orienttions. I could certailny go through 4 * 90 degree rotations without incident, but more than that and something in the underlying controls was not happy. I didn’t try to get to the bottom of it, because even if I did there would not be anything I could do other than report it. Needed another approach.