This is the accompanying Gist to the blog post at cayas.de.
The OnOrientation MarkupExtension helps to make XAML pages automatically adapt to orientation changes.
By enabling developers to provide different values for their view's properties directly inline in XAML, similiar to other MarkupExtensions like OnPlatform and OnIdiom.
For example it can be used to rearrange a Grid's ColumnDefinitions to accommodate for orientation changes:
<Grid ColumnDefinitions="{OnOrientation Default='*', Landscape='*,*', TypeConverter={x:Type ColumnDefinitionCollectionTypeConverter}}">
(Why ColumnDefinitionCollectionTypeConverter needs to be specified here is explained below or in the blog post)
- Install
CommunityToolkit.Mauiinto the project - Add
UseMauiCommunityToolkit()toMauiProgram.cswhen configuring theMauiAppBuilder - Add both classes,
OnOrientationExtension.csandOnOrientationSource.cs, to the .NET MAUI project - Add the namespace alias to the XAML file
- Use
OnOrientationeither inline as MarkupExtension in attribute syntax, or via property element syntax
Make sure to always specify a value for Default.
<Label Grid.Row="{OnOrientation Default=0, Landscape=1}" />
Since the values you provide in a MarkupExtension must be of a primitive type like int or string and type conversion using TypeConverters does not kick in, sometimes you may need to use x:Static.
<Label HorizontalOptions="{OnOrientation Default={x:Static LayoutOptions.Start}, Landscape={x:Static LayoutOptions.Center}}" />
If the value is more complex and you know which TypeConverter should be used, you can specify it.
OnOrientation can then perform type conversion using the provided Type of TypeConverter.
<Grid ColumnDefinitions="{OnOrientation Default='*', Landscape='*,*', TypeConverter={x:Type ColumnDefinitionCollectionTypeConverter}}">
When a complex value is needed and no TypeConverter exists, then you can also use property element syntax to specify the different values. Although one can argue that this is way too verbose for practical use.
<Grid.ColumnDefinitions>
<ext:OnOrientation>
<ext:OnOrientation.Default>
<ColumnDefinitionCollection>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0" />
</ColumnDefinitionCollection>
</ext:OnOrientation.Default>
<ext:OnOrientation.Landscape>
<ColumnDefinitionCollection>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</ColumnDefinitionCollection>
</ext:OnOrientation.Landscape>
</ext:OnOrientation>
</Grid.ColumnDefinitions>
This syntax could also be used to switch out entire views.
<ContentView>
<ContentView.Content>
<ext:OnOrientation>
<Label Text="This text is visible in Default" />
<ext:OnOrientation.Landscape>
<Label Text="This text is visible in Landscape" />
</ext:OnOrientation.Landscape>
</ext:OnOrientation>
</ContentView.Content>
</ContentView>
- Only works with Android and iOS, since OnOrientationExtension uses the Orientation provided by DeviceDisplay.MainDisplayInfo.Orientation
- Value cannot be a BindingExpression
Hi @grabnerM ,
to me it sounds like you are missing the namespace declaration in your XAML. In my code OnOrientation is prefixed with
ext:as that is the alias I have given for the namespace that contains the OnOrientationExtension class.It should also work with Margins if applied correctly.
Show me your specific code and I can help you with that.