Adaptive Trigger, du responsive dans les applications Windows 10 !

Les applications universelles Windows 10 (UWP) peuvent s’exécuter sur de nombreux périphériques avec des résolutions différentes (des ordinateurs, des tablettes, des téléphones, …). Il peut être bon, pour le confort de l’utilisateur, de pouvoir modifier l’interface de l’application en fonction de la résolution cible (en fonction de la largeur et/ou de la hauteur).

Ce comportement est déjà présent sur les sites web, avec souvent deux designs très différents en fonction de la plateforme ciblée (en général un design pour le site en mobile et un autre pour le site en tablette/ordinateur). Pour réaliser cela en web, on utilise des media queries, avec UWP nous avons les VisualState et les AdaptiveTrigger qui fonctionnent de la même manière.

Un VisualState permet de modifier l’apparence des éléments de la page en changeant les propriétés de ces éléments.

Un AdaptiveTrigger est une règle qui déclenche le VisualState associé lorsque la hauteur ou la largeur de la fenêtre est modifiée. Pour définir quand doit se déclencher cette règle, il existe deux propriétés :

  • MinWindowHeight : permet de définir la hauteur minimale de la fenêtre pour laquelle doit s’exécuter la règle
  • MinWindowWidth : permet de définir la largeur minimale de la fenêtre pour laquelle doit s’exécuter la règle

Comment cela fonctionne ?

Prenons l’exemple d’une application qui définit 3 blocs, un bleu, un blanc et un rouge. Mon objectif est d’afficher les 3 blocs côte-à-côte en “normal”, de supprimer le bloc blanc en “tablette” et sur “téléphone” afficher les 3 blocs l’un en dessous de l’autre.

Je vais pouvoir réaliser cela en combinant VisualState et AdaptiveTrigger. Je définis donc 3 VisualState et pour chacun AdaptiveTrigger :

  • Un VisualState “NormalState” qui est celui défini quand la largeur de la fenêtre est supérieure à 1100 pixels,
  • Un VisualState “TabletState” qui est celui défini quand la largeur de la fenêtre est comprise entre 600 et 1100 pixels,
  • Un VisualState “PhoneState” qui est celui défini quand la largeur de la fenêtre est inférieure à 600 pixels.

Voici donc le code que j’ai défini pour réaliser le design voulu.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
      x:Name="MainGrid">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <!-- Visual State pour ordinateur > à 1100px -->
            <VisualState x:Name="NormalState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="1100" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MainGrid.RowDefinitions[1].Height"
                            Value="auto" />
                    <Setter Target="MainGrid.RowDefinitions[2].Height"
                            Value="auto" />
                    <Setter Target="MainGrid.ColumnDefinitions[1].Width"
                            Value="*" />
                    <Setter Target="MainGrid.ColumnDefinitions[2].Width"
                            Value="*" />
                    <Setter Target="SecondGrid.(Grid.Column)"
                            Value="1" />
                    <Setter Target="SecondGrid.(Grid.Row)"
                            Value="0" />
                    <Setter Target="SecondGrid.Visibility"
                            Value="Visible" />
                    <Setter Target="ThirdGrid.(Grid.Column)"
                            Value="2" />
                    <Setter Target="ThirdGrid.(Grid.Row)"
                            Value="0" />
                </VisualState.Setters>
            </VisualState>

            <!-- Visual State pour tablette entre 600 et 1100 px -->
            <VisualState x:Name="TabletState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="600" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MainGrid.RowDefinitions[1].Height"
                            Value="auto" />
                    <Setter Target="MainGrid.RowDefinitions[2].Height"
                            Value="auto" />
                    <Setter Target="MainGrid.ColumnDefinitions[1].Width"
                            Value="*" />
                    <Setter Target="MainGrid.ColumnDefinitions[2].Width"
                            Value="auto" />
                    <Setter Target="ThirdGrid.(Grid.Column)"
                            Value="1" />
                    <Setter Target="ThirdGrid.(Grid.Row)"
                            Value="0" />
                    <Setter Target="SecondGrid.Visibility"
                            Value="Collapsed" />
                </VisualState.Setters>
            </VisualState>
            
            <!-- Visual State pour phone < 600px -->
            <VisualState x:Name="PhoneState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MainGrid.RowDefinitions[1].Height"
                            Value="*" />
                    <Setter Target="MainGrid.RowDefinitions[2].Height"
                            Value="*" />
                    <Setter Target="MainGrid.ColumnDefinitions[1].Width"
                            Value="auto" />
                    <Setter Target="MainGrid.ColumnDefinitions[2].Width"
                            Value="auto" />
                    <Setter Target="SecondGrid.(Grid.Column)"
                            Value="0" />
                    <Setter Target="SecondGrid.(Grid.Row)"
                            Value="1" />
                    <Setter Target="ThirdGrid.(Grid.Column)"
                            Value="0" />
                    <Setter Target="ThirdGrid.(Grid.Row)"
                            Value="2" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Width="*" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>

    <!-- Bloc tout le temps visible -->
    <Grid x:Name="FirstGrid"
          Grid.Column="0"
          Grid.Row="0"
          Background="Blue" />
    <!-- Bloc moins important, non visible sur tablette -->
    <Grid x:Name="SecondGrid"
          Grid.Column="2"
          Grid.Row="0"
          Background="White" />
    <!-- Bloc tout le temps visible -->
    <Grid x:Name="ThirdGrid"
          Grid.Column="1"
          Grid.Row="0"
          Background="Red" />
</Grid>

 

Voici le rendu final, qui est donc conforme à nos attentes, et ce uniquement en ayant défini 3 VisualState :

[gickr.com]_1249e237-eb4d-0bb4-ad57-f5269331f675

 

Attention, il est bon de savoir que le VisualStateManager doit être défini sur le premier élément de la page pour qu’il soit pris en compte.

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus