Updated LayoutRules Code

I updated the LayoutRules sample attached to the //build/ post I made the other day. This version is much more comprehensive and easier to use. The sample usage is slightly more realistic, as well.

At its core, the sample exposes a LayoutableUserControl and a LayoutablePage that let you specify a set of layout rules that are evaluated every time the control is re-measured. Each rule implements the ILayoutRule interface that exposes a mechanism to check if the rule applies given the control's current size (ILayoutEvaluator.Evaluate) and a mechanism to invoke the functionality of the rule (ICommand.Execute).

From there some primitive layout evaluators (like WidthLayoutEvaluator - checks if the current control's width is smaller than a given width or not), some primitive commands (like GoToVisualStateCommand - goes to a named visual state), some compound evaluators / commands, and some more complex base types are defined.

The end result is a set of high-level rules that can be used for many basic operations. For example, one of the rules used in the sample is the following WidthUpdatePropertyRule:

<layout:WidthUpdatePropertyRule
DisplayName="Make buttons smaller"
Width="550"
ComparisonType="LessThan"
Name="ExplorerViewProperties"
Property="ButtonSize"
Value="50,50"
ValueIfFalse="80,80"
ValueConverter="{StaticResource SizeConverter}" />

As the DisplayName property indicates, this is used to update the ButtonSize property of the ExplorerViewProperties named resource to 50x50 if the Width of the control is less than 550px, or to 80x80 if not. Parts of the UI are data-bound to this object, and so they will update dynamically.

Another example:

<layout:HeightGoToVisualStateRule
DisplayName="Make text smaller"
Height="300"
ComparisonType="GreaterThanOrEqualTo"
VisualStateName="LargeText"
VisualStateNameIfFalse="SmallText"/>

This rule switches to the visual state LargeText if the Height is at least 300px, otherwise it switches to the SmallText visual state.

Of course, all pixel values are in effective pixels (aka view pixels). We don't care what the actual physical resolution of the display is. You can also use some of the building-blocks to make more complex rules (at the expense of more XAML).

You might ask yourself why something like this doesn't come standard as part of the platform or the SDK. When we were working on Windows Phone 8.1, we had many discussions about this very topic, but ultimately we didn't ship any layout-helper controls like those in this sample for two basic reasons:

  1. There is no tooling experience (Visual Studio or Blend design surface) for these layout rules; you need to reason about them without being able to see the results (or, more likely, take a starting guess and then use trial-and-error to perfect it). There is a tooling experience for Visual States, but not for automatically switching between them while designing the control
  2. We weren't able to settle on what the right long-term approach should be for adaptive layout. This is just one approach of many possible approaches, and whilst it is convenient for some scenarios we don't (yet) know what the best solution will look like in the future

Anyway, until such time as we solve the problem in some hypothetical future release, you can use this code (or hack it any way you see fit) in order to get your own apps up and running. If you have comments, suggestions, etc. feel free to post them below!

(P.S. I apologize for the lack of comments in the code. Hopefully when I do a full blog post for the //build talk I will have the code properly commented... and maybe even tested!)