Building applications is hard, and making them compatible on multiple platforms is a headache. You can either create multiple apps for specific platforms and use
TargetDeviceFamily
like in this
tutorial or use
AdaptiveTriggers
so that you can adapt your view to the screen of a device.
On the
Dailymotion Windows 10 application we wanted to use the same views on Mobile and Desktop devices. This is where adaptive triggers come to the rescue.
In this tutorial I will explain how to use AdaptiveTriggers
to resize the width of our ItemTemplate
inside a Gridview
, when the application changes size. When the application is reduced to a certain size, I want the ItemTemplate
that has a fixed size (300 pixels) to take up the whole width of the page.
Because a Gif is better then a 1000 words, this is the effect that I would like:

This tutorial will cover:
- What are
AdaptiveTriggers
- How to use
AdaptiveTriggers
on a DataTemplate
What are Adaptive Triggers
Quick description: adaptive triggers allow you to create a rule (or set of rules) that can trigger a change in the visual state of your application (you can change the Size/Color/Visibility/etc of an element for example). This can allow you to resize elements without having to listen to the Window.SizeChanged event (that's AWESOME! let's do this!).
A lot more information can be found on MSDN
here
How to use adaptive triggers on Items inside a GridView
The trick to using adaptive triggers inside a GridView
is to implement it inside theDataTemplate
, however, you can't create a
<VisualStateManager.VisualStateGroups />
inside a resource file, so how is this possible?
You need to create a UserControl
that you reference in your DataTemplate
like this:
<DataTemplate>
<controls:AdaptiveCatItem />
</DataTemplate>
And you set your VisualStateManager
in the UserControl.
Here is an example on my User Control:
<UserControl x:Class="AdaptiveTriggers.Win10.Controls.AdaptiveCatItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="TemplateRoot"
Height="250"
Width="300"
HorizontalAlignment="Stretch"
Margin="2"
VerticalAlignment="Top">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="VisualStateNarrow">
<VisualState.StateTriggers>
<AdaptiveTrigger x:Name="VisualStateNarrowTrigger" MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TemplateRoot.Width" Value="Auto" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateNormal">
<VisualState.StateTriggers>
<AdaptiveTrigger x:Name="VisualStateNormalTrigger" MinWindowWidth="521" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TemplateRoot.Width" Value="300" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="190" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Row="0"
HorizontalAlignment="Center"
Source="{Binding ThumbnailUri}"
Stretch="UniformToFill" />
<Grid Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Background="Transparent">
<TextBlock Grid.Row="0"
Margin="5,5,5,5"
Text="{Binding Title,
FallbackValue='This is the cat image of the year'}"
/>
</Grid>
</Grid>
</UserControl>
My VisualStateManager
has two important AdaptiveTriggers
. The first one is named VisualStateNarrowTrigger
with a MinWindowWidth
of 0 and another one named VisualStateNormalTrigger
with a MinWindowWidth
of 521. In this example, VisualStateNormalTrigger
is the most important one.
What VisualStateNormalTrigger
does is when the application is larger than 521 pixels then my items in the GridView
have a width of 300. When my application width is smaller than 521 pixels the trigger VisualStateNarrowTrigger
is fired and the width of my items in the GridView
are set to Auto (which means that it will take up as much space as it can).
Going back to my VisualStateManager
, here are the two important parts:
- As mentioned above,
VisualState
allows me to set the width to auto on my grid element named TemplateRoot, when the application has a width of 0 pixels or more:
<VisualState.StateTriggers>
<AdaptiveTrigger x:Name="VisualStateNarrowTrigger" MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TemplateRoot.Width" Value="Auto" />
</VisualState.Setters>
- This
VisualState
allows me to set the Width to 300 on my grid element named TemplateRoot when the width of my application is 521 pixel or more:
<VisualState.StateTriggers>
<AdaptiveTrigger x:Name="VisualStateNormalTrigger" MinWindowWidth="521" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TemplateRoot.Width" Value="300" />
</VisualState.Setters>
And there you have it, you can now resize the items that are inside your GridView when your application is resized without using any C# code

All of the code can be found on Github
here
Happy Coding =)
PS: as you can guess I like cats ^^