Implementing Adaptive Layout In UWP App

Introduction 

In this article I've tried to explain the use of <VisualStateManager> and <AdaptiveTrigger> to achieve Adaptive Layout for Universal Windows App. For that let's take an example where if the window width will be 700px or higher, we will divide the content in three columns, and if the window width will be less than 600px then we'll merge those columns and divide into three rows.
 
Here's how the UI will look in both cases:

Desktop UI:
 
 
Mobile UI:

 

XAML Code to achieve this

To achieve this Adaptive Layout UI in UWP app we need to use <VisualStateMamager> and <AdaptiveTrigger> in XAML code.

The following is the XAML code for the UI shown in the image. 
  1. <Page  
  2.     x:Class="Testing2.AdaptiveLayoutPage"  
  3.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  4.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  5.     xmlns:local="using:Testing2"  
  6.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  7.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  8.     mc:Ignorable="d">  
  9.   
  10.     <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">  
  11.   
  12.         <VisualStateManager.VisualStateGroups>  
  13.             <VisualStateGroup>  
  14.                   
  15.                 <VisualState x:Name="visualstateMobile">  
  16.                     <VisualState.StateTriggers>  
  17.                         <AdaptiveTrigger MinWindowWidth="0" />  
  18.                     </VisualState.StateTriggers>  
  19.                     <VisualState.Setters>  
  20.                         <Setter Target="img.(Grid.Row)" Value="0" />  
  21.                         <Setter Target="img.(Grid.Column)" Value="0" />  
  22.                         <Setter Target="img.(Grid.RowSpan)" Value="1" />  
  23.                         <Setter Target="img.(Grid.ColumnSpan)" Value="3" />  
  24.   
  25.                         <Setter Target="tbSecond.(Grid.Row)" Value="1" />  
  26.                         <Setter Target="tbSecond.(Grid.Column)" Value="0" />  
  27.                         <Setter Target="tbSecond.(Grid.RowSpan)" Value="1" />  
  28.                         <Setter Target="tbSecond.(Grid.ColumnSpan)" Value="3" />  
  29.   
  30.                         <Setter Target="tbThird.(Grid.Row)" Value="2" />  
  31.                         <Setter Target="tbThird.(Grid.Column)" Value="0" />  
  32.                         <Setter Target="tbThird.(Grid.RowSpan)" Value="1" />  
  33.                         <Setter Target="tbThird.(Grid.ColumnSpan)" Value="3" />  
  34.                     </VisualState.Setters>  
  35.                 </VisualState>  
  36.   
  37.                 <VisualState x:Name="visualstateDesktop">  
  38.                     <VisualState.StateTriggers>  
  39.                         <AdaptiveTrigger MinWindowWidth="600" />  
  40.                     </VisualState.StateTriggers>  
  41.                     <VisualState.Setters>  
  42.                         <Setter Target="img.(Grid.Row)" Value="0" />  
  43.                         <Setter Target="img.(Grid.Column)" Value="0" />  
  44.                         <Setter Target="img.(Grid.RowSpan)" Value="2" />  
  45.                         <Setter Target="img.(Grid.ColumnSpan)" Value="1" />  
  46.   
  47.                         <Setter Target="tbSecond.(Grid.Row)" Value="0" />  
  48.                         <Setter Target="tbSecond.(Grid.Column)" Value="1" />  
  49.                         <Setter Target="tbSecond.(Grid.RowSpan)" Value="3" />  
  50.                         <Setter Target="tbSecond.(Grid.ColumnSpan)" Value="1" />  
  51.   
  52.                         <Setter Target="tbThird.(Grid.Row)" Value="0" />  
  53.                         <Setter Target="tbThird.(Grid.Column)" Value="2" />  
  54.                         <Setter Target="tbThird.(Grid.RowSpan)" Value="3" />  
  55.                         <Setter Target="tbThird.(Grid.ColumnSpan)" Value="1" />  
  56.                     </VisualState.Setters>  
  57.                 </VisualState>  
  58.   
  59.             </VisualStateGroup>  
  60.         </VisualStateManager.VisualStateGroups>  
  61.           
  62.         <ScrollViewer>  
  63.             <Grid>  
  64.                 <Grid.RowDefinitions>  
  65.                     <RowDefinition />  
  66.                     <RowDefinition />  
  67.                     <RowDefinition />  
  68.                 </Grid.RowDefinitions>  
  69.                 <Grid.ColumnDefinitions>  
  70.                     <ColumnDefinition />  
  71.                     <ColumnDefinition />  
  72.                     <ColumnDefinition />  
  73.                 </Grid.ColumnDefinitions>  
  74.   
  75.                 <Image x:Name="img" Source="Assets/image.png" Grid.RowSpan="2" Margin="12" />  
  76.   
  77.                 <TextBlock x:Name="tbSecond" Grid.Column="1" Grid.RowSpan="3" TextWrapping="Wrap" Margin="12"  
  78.                    Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam elementum, lectus ac tempus viverra, odio lectus placerat sem, vestibulum molestie tellus velit et metus. Aliquam posuere magna at augue semper, ut egestas nisl varius. Curabitur venenatis elit lacus, quis aliquam nibh varius id. Nulla vehicula tortor risus, a facilisis diam scelerisque sed. Quisque eleifend orci eget nibh semper, ut feugiat mi auctor. Sed sit amet ultrices libero, non aliquet metus. Vivamus non neque purus. Sed sodales congue consectetur. Maecenas cursus sollicitudin lectus. Donec neque est, ullamcorper facilisis magna at, feugiat maximus nibh. Donec accumsan velit eget justo iaculis aliquam. Phasellus dui neque, interdum a congue eu, dapibus nec risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam at condimentum odio. Nunc vitae pretium leo. Ut finibus sodales ipsum a convallis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eros ligula, molestie sodales convallis non, ultrices sed risus. Sed eleifend lobortis dictum. Fusce finibus sapien nec mauris gravida, eu egestas leo sodales. Pellentesque neque turpis, consequat sed nisl eu, auctor condimentum erat. Curabitur sagittis urna at nulla tincidunt, eu cursus leo commodo. Nullam consectetur mi et congue semper. Nullam lacus arcu, rhoncus at justo fringilla, commodo vestibulum diam. Sed euismod quam quis lacus tristique hendrerit." />  
  79.   
  80.                 <TextBlock x:Name="tbThird" Grid.Column="2" Grid.RowSpan="3" TextWrapping="Wrap" Margin="12"  
  81.                    Text="Fusce sed metus justo. Quisque libero mauris, egestas quis velit id, volutpat cursus nunc. Aenean lacinia mauris sit amet viverra feugiat. Maecenas molestie pulvinar quam vel mollis. Donec nec congue turpis. Suspendisse luctus cursus nisl, vel bibendum diam sollicitudin quis. Ut semper dui quis justo cursus, quis dictum dui scelerisque. Nulla porttitor varius luctus. Proin egestas diam tempus elementum mollis. Nulla iaculis quam lacus, nec laoreet enim efficitur ultricies. In fringilla velit dui, sit amet viverra libero accumsan at. Pellentesque in laoreet lorem. Curabitur ut facilisis elit. Proin congue quam pretium, interdum ligula tempor, porttitor orci. Maecenas cursus sollicitudin lectus. Donec neque est, ullamcorper facilisis magna at, feugiat maximus nibh. Donec accumsan velit eget justo iaculis aliquam. Phasellus dui neque, interdum a congue eu, dapibus nec risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam at condimentum odio. Nunc vitae pretium leo. Ut finibus sodales ipsum a convallis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eros ligula, molestie sodales convallis non, ultrices sed risus. Sed eleifend lobortis dictum. Fusce finibus sapien nec mauris gravida, eu egestas leo sodales. Pellentesque neque turpis, consequat sed nisl eu, auctor condimentum erat. Curabitur sagittis urna at nulla tincidunt, eu cursus leo commodo. Nullam consectetur mi et congue semper. Nullam lacus arcu, rhoncus at justo fringilla, commodo vestibulum diam. Sed euismod quam quis lacus tristique hendrerit. Ut tempor enim non libero blandit, in venenatis urna eleifend. Nam malesuada tincidunt vestibulum. Vivamus iaculis consectetur fringilla. Phasellus luctus mi at massa tempus faucibus. Phasellus vitae laoreet ante. Sed et scelerisque tortor, fermentum tincidunt lorem. Suspendisse et orci et ante pretium blandit." />  
  82.   
  83.             </Grid>  
  84.         </ScrollViewer>  
  85.   
  86.     </Grid>  
  87. </Page>  
We don't have to write any C# code to achieve this Responsive UI. Here the text we've used is Lorem Ipsum so don't worry about it.
 
Explanation:

The key point to note here is the way we can change the values of any specific property used in out XAML page's UI controls. In our example we have changed the values of (Grid.Row), (Grid.Column), Rowspan and Columnspan for Image and textblock used in the page. While having more width to show, we've divided the contents in three columns, and while having small width we've assigned ColumnSpan to 3 and divided into Rows. 

The scenario I've covered here is the most-used scenario while developing apps for multiple resolutions which have a lot of content/information to show.
 


Similar Articles