To design 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:
- <VisualState.StateTriggers>
- <AdaptiveTrigger MinWindowWidth="400" />
- </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 final implementation in real-time. Given below are the steps to create a sample application.
Step 1: Create Universal Windows App
Open Visual Studio 2015 > New Project > Windows > Universal > Blank 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 class with the following properties.
- public class MusicItem {
- public int Id {
- get;
- set;
- }
- public string Title {
- get;
- set;
- }
- public string Info {
- get;
- set;
- }
- public string DateLine {
- get;
- set;
- }
- public string Image {
- get;
- set;
- }
- }
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.
- public class MusicItemManager {
- public static ObservableCollection < MusicItem > getNewsItems() {
- var items = new List < MusicItem > ();
- items.Add(new MusicItem() {
- Id = 1, Title = "Lorem Ipsum", Info = "doro sit amet", DateLine = "Nunc tristique nec", Image = "Assets/image1.jpg"
- });
- items.Add(new MusicItem() {
- Id = 2, Title = "Etiam ac felis viverra", Info = "vulputate nisl ac, aliquet nisi", DateLine = "tortor porttitor, eu fermentum ante congue", Image = "Assets/image2.jpg"
- });
- items.Add(new MusicItem() {
- Id = 3, Title = "Integer sed turpis erat", Info = "Sed quis hendrerit lorem, quis interdum dolor", DateLine = "in viverra metus facilisis sed", Image = "Assets/image3.jpg"
- });
- items.Add(new MusicItem() {
- Id = 4, Title = "Proin sem neque", Info = "aliquet quis ipsum tincidunt", DateLine = "Integer eleifend", Image = "Assets/image4.jpg"
- });
- items.Add(new MusicItem() {
- Id = 5, Title = "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"
- });
- return new ObservableCollection < MusicItem > (items);
- }
- }
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 the below code inside our UserControl.xaml.
- <StackPanel x:Name="stackPanel" Width="200" Height="275" Margin="10" HorizontalAlignment="Center">
- <VisualStateManager.VisualStateGroups>
- <VisualStateGroup x:Name="VisualStateGroup">
- <VisualState x:Name="Wide">
- <VisualState.Setters>
- <Setter Target="txtHeadLine.FontSize" Value="26" />
- <Setter Target="txtHeadLine.Foreground" Value="Green" />
- <Setter Target="stackPanel.Width" Value="400" />
- <Setter Target="stackPanel.Height" Value="400" /> </VisualState.Setters>
- <VisualState.StateTriggers>
- <AdaptiveTrigger MinWindowWidth="800" /> </VisualState.StateTriggers>
- </VisualState>
- <VisualState x:Name="Narrow">
- <VisualState.Setters>
- <Setter Target="txtHeadLine.FontSize" Value="18" />
- <Setter Target="txtHeadLine.Foreground" Value="Coral" />
- <Setter Target="stackPanel.Width" Value="200" />
- <Setter Target="stackPanel.Height" Value="275" /> </VisualState.Setters>
- <VisualState.StateTriggers>
- <AdaptiveTrigger MinWindowWidth="400" /> </VisualState.StateTriggers>
- </VisualState>
- </VisualStateGroup>
- </VisualStateManager.VisualStateGroups>
- <Image x:Name="image" Source="{x:Bind Music.Image}" HorizontalAlignment="Stretch" />
- <TextBlock x:Name="txtHeadLine" Text="{x:Bind Music.Title}" FontSize="18" HorizontalAlignment="Center" TextWrapping="Wrap" MaxLines="2" />
- <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.
- public MusicItem Music { get { return this.DataContext as MusicItem; } }
And, add the below line inside constructor of Codebehind file.
- this.DataContextChanged += (s, e) => Bindings.Update();
This will be used to update our databinding.
Our basic structure is ready with 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:
- <GridView ItemsSource="{x:Bind MusicItems,Mode=OneWay}" Margin="10" Name="gridView">
- <GridView.ItemTemplate>
- <DataTemplate x:DataType="data:MusicItem">
- <local:MusicItemTemplate HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> </DataTemplate>
- </GridView.ItemTemplate>
- </GridView>
Here, we are using x:DataType in data template. It tells the control which kind of data is going to be used in our data control for data binding.
Read more about dataTemplate:DataType at MSDN. We’ve to define this datatype at the page as,
- xmlns:data="using:UWPAdaptiveLayoutSample.Model"
Now, come to MainPage.xaml.cs. Define an Observable collection, as defined below.
- private ObservableCollection<MusicItem> MusicItems;
After defining Observable Collection, we’ll fill our collection and bind it to our GridView.
- MusicItems = MusicItemManager.getNewsItems();
- gridView.DataContext = MusicItems;
Now, all things are ready. Just run the 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.