How To Design Adaptive Layout For Windows Desktop And Mobile

Introduction 

 
To design an adaptive layout, we’ll use ViusalStateManager and adaptive trigger.
 
VisualStateManager supports the most important UI feature - controlling the state of control and providing transitions between different states of a control. For more info, visit MSDN.
 
Adaptive Trigger, in simple words, triggers the visual state when windows properties (e.g. Height or width) change.
 
For example
  1. <VisualState.StateTriggers>    
  2.     <AdaptiveTrigger MinWindowWidth="400" />     
  3. </VisualState.StateTriggers>    
So, this AdaptiveTrigger will be triggered when the window width is less than or equal to 400 pixels. For more info, go to MSDN.
 
Now, we’ll look into the final implementation in real-time. Given below are the steps to create a sample application.
 
Step 1
 

Create a Universal Windows App

 
Open Visual Studio 2015 > New Project > Windows > Universal > Blank App.
 
Create Universal Windows App
 
Step 2
 

Add a Model

 
Add a Model folder in your project inside which we’ll create a class with the name “MusicItem.cs”, Now, we’ll define a class with the following properties.
  1. public class MusicItem {    
  2.     public int Id {    
  3.         get;    
  4.         set;    
  5.     }    
  6.     public string Title {    
  7.         get;    
  8.         set;    
  9.     }    
  10.     public string Info {    
  11.         get;    
  12.         set;    
  13.     }    
  14.     public string DateLine {    
  15.         get;    
  16.         set;    
  17.     }    
  18.     public string Image {    
  19.         get;    
  20.         set;    
  21.     }    
  22. }    
Step 3
 

Add a Helper class

 
Now, we add another class as “MusicItemManager” which will be used to load data for our model class with some dummy data.
  1. public class MusicItemManager {    
  2.     public static ObservableCollection < MusicItem > getNewsItems() {    
  3.         var items = new List < MusicItem > ();    
  4.         items.Add(new MusicItem() {    
  5.             Id = 1Title = "Lorem Ipsum"Info = "doro sit amet"DateLine = "Nunc tristique nec"Image = "Assets/image1.jpg"    
  6.         });    
  7.         items.Add(new MusicItem() {    
  8.             Id = 2Title = "Etiam ac felis viverra"Info = "vulputate nisl ac, aliquet nisi"DateLine = "tortor porttitor, eu fermentum ante congue"Image = "Assets/image2.jpg"    
  9.         });    
  10.         items.Add(new MusicItem() {    
  11.             Id = 3Title = "Integer sed turpis erat"Info = "Sed quis hendrerit lorem, quis interdum dolor"DateLine = "in viverra metus facilisis sed"Image = "Assets/image3.jpg"    
  12.         });    
  13.         items.Add(new MusicItem() {    
  14.             Id = 4Title = "Proin sem neque"Info = "aliquet quis ipsum tincidunt"DateLine = "Integer eleifend"Image = "Assets/image4.jpg"    
  15.         });    
  16.         items.Add(new MusicItem() {    
  17.             Id = 5Title = "Mauris bibendum non leo vitae tempor"Info = "In nisl tortor, eleifend sed ipsum eget"DateLine = "Curabitur dictum augue vitae elementum ultrices"Image = "Assets/image5.jpg"    
  18.         });    
  19.         return new ObservableCollection < MusicItem > (items);    
  20.     }    
  21. }    
Add 5 images in project’s assets folder for our data and name them as image1, image2 and so on.
 
Step 4
 

Add a UserControl

 
Right click on project > Add > New Item - UserControl - Name it as - MusicItemTemplate.xaml > Click on add button.
 
This user control will act as our DataTemplate in our application.
 
Add a UserControl
 
Add the below code inside our UserControl.xaml.
  1. <StackPanel x:Name="stackPanel" Width="200" Height="275" Margin="10" HorizontalAlignment="Center">    
  2.     <VisualStateManager.VisualStateGroups>    
  3.         <VisualStateGroup x:Name="VisualStateGroup">    
  4.             <VisualState x:Name="Wide">    
  5.                 <VisualState.Setters>    
  6.                     <Setter Target="txtHeadLine.FontSize" Value="26" />    
  7.                     <Setter Target="txtHeadLine.Foreground" Value="Green" />    
  8.                     <Setter Target="stackPanel.Width" Value="400" />    
  9.                     <Setter Target="stackPanel.Height" Value="400" /> </VisualState.Setters>    
  10.                 <VisualState.StateTriggers>    
  11.                     <AdaptiveTrigger MinWindowWidth="800" /> </VisualState.StateTriggers>    
  12.             </VisualState>    
  13.             <VisualState x:Name="Narrow">    
  14.                 <VisualState.Setters>    
  15.                     <Setter Target="txtHeadLine.FontSize" Value="18" />    
  16.                     <Setter Target="txtHeadLine.Foreground" Value="Coral" />    
  17.                     <Setter Target="stackPanel.Width" Value="200" />    
  18.                     <Setter Target="stackPanel.Height" Value="275" /> </VisualState.Setters>    
  19.                 <VisualState.StateTriggers>    
  20.                     <AdaptiveTrigger MinWindowWidth="400" /> </VisualState.StateTriggers>    
  21.             </VisualState>    
  22.         </VisualStateGroup>    
  23.     </VisualStateManager.VisualStateGroups>    
  24.     <Image x:Name="image" Source="{x:Bind Music.Image}" HorizontalAlignment="Stretch" />    
  25.     <TextBlock x:Name="txtHeadLine" Text="{x:Bind Music.Title}" FontSize="18" HorizontalAlignment="Center" TextWrapping="Wrap" MaxLines="2" />    
  26.     <TextBlock x:Name="txtSubHead" Text="{x:Bind Music.Info}" HorizontalAlignment="Center" Margin="0,10,0,0" /> </StackPanel>    
Step 5
 

Code Behind of UserControl

 
Add the below code in code behind file of our user control. This will be used for data binding with our data template.
  1. public MusicItem Music { get { return this.DataContext as MusicItem; } }      
And, add the below line inside the constructor of code-behind file.
  1. this.DataContextChanged += (s, e) => Bindings.Update();      
This will be used to update our data-binding.
 
Our basic structure is ready with the Model data and Data Template. Now, just one last thing is remaining. We’ve to define the data control to display all the data and bind all together.
 
Step 6
 

Define DataControl(GridView)

 
Now, at our MainPage.Xaml, define GridView, as shown below:
  1. <GridView ItemsSource="{x:Bind MusicItems,Mode=OneWay}" Margin="10" Name="gridView">    
  2.     <GridView.ItemTemplate>    
  3.         <DataTemplate x:DataType="data:MusicItem">    
  4.             <local:MusicItemTemplate HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> </DataTemplate>    
  5.     </GridView.ItemTemplate>    
  6. </GridView>    
Here, we are using x: DataType in the data template. It tells the control which kind of data is going to be used in our data controller for data binding.
 
Read more about data template: DataType at MSDN.  We’ve to define this datatype at the page as,
  1. xmlns:data="using:UWPAdaptiveLayoutSample.Model"      
Now, come to MainPage.xaml.cs. Define an Observable collection, as defined below.
  1. private ObservableCollection<MusicItem> MusicItems;      
After defining the Observable Collection, we’ll fill our collection and bind it to our GridView.
  1. MusicItems = MusicItemManager.getNewsItems();     
  2. gridView.DataContext = MusicItems;     
Now, all things are ready. Just run the application.
 
application
 
application
 

Summary

 
In this article, we learned how to design adaptive layout, how to target it for multiple screens, VisualStateManager and AdaptiveTrigger. In a similar fashion, we can target different devices, like Mobile, tablet, or Desktop.
 
Now, you can try designing a screen which will target different sizes of windows.