Attribut x:Load

Vous pouvez utiliser x :Load pour optimiser le démarrage, la création d’arborescence visuelle et l’utilisation de la mémoire de votre application XAML. L’utilisation de x :Load a un effet visuel similaire à Visibility, sauf que lorsque l’élément n’est pas chargé, sa mémoire est libérée et en interne, un petit espace réservé est utilisé pour marquer sa place dans l’arborescence visuelle.

L’élément d’interface utilisateur attribué avec x :Load peut être chargé et déchargé via du code ou à l’aide d’une expression x :Bind . Cela est utile pour réduire les coûts des éléments qui sont présentés rarement ou conditionnellement. Lorsque vous utilisez x :Load sur un conteneur tel que Grid ou StackPanel, le conteneur et tous ses enfants sont chargés ou déchargés en tant que groupe.

Le suivi des éléments différés par l’infrastructure XAML ajoute environ 600 octets à l’utilisation de la mémoire pour chaque élément attribué avec x :Load, afin de tenir compte de l’espace réservé. Par conséquent, il est possible de surutiliser cet attribut dans la mesure où vos performances diminuent réellement. Nous vous recommandons de l’utiliser uniquement sur les éléments qui doivent être masqués. Si vous utilisez x :Load sur un conteneur, la surcharge est payée uniquement pour l’élément avec l’attribut x :Load.

Important

L’attribut x :Load est disponible à partir de Windows 10, version 1703 (Creators Update). La version minimale ciblée par votre projet Visual Studio doit être Windows 10 Creators Update (10.0, build 15063) pour pouvoir utiliser x:Load.

Utilisation des attributs XAML

<object x:Load="True" .../>
<object x:Load="False" .../>
<object x:Load="{x:Bind Path.to.a.boolean, Mode=OneWay}" .../>

Chargement d’éléments

Il existe plusieurs façons de charger les éléments :

  • Utilisez une expression x :Bind pour spécifier l’état de chargement. L’expression doit retourner true pour charger et false pour décharger l’élément.
  • Appelez FindName avec le nom que vous avez défini sur l’élément.
  • Appelez GetTemplateChild avec le nom que vous avez défini sur l’élément.
  • Dans visualState, utilisez une animation Setter ou Storyboard qui cible l’élément x :Load.
  • Ciblez l’élément déchargé dans n’importe quel storyboard.

REMARQUE : Une fois l’instanciation d’un élément démarrée, elle est créée sur le thread d’interface utilisateur, de sorte qu’elle peut entraîner l’ébreuxtage de l’interface utilisateur si trop de choses sont créées en même temps.

Une fois qu’un élément différé est créé de l’une des manières répertoriées précédemment, plusieurs choses se produisent :

  • L’événement Loaded sur l’élément est déclenché.
  • Le champ pour x :Name est défini.
  • Toutes les liaisons x :Bind sur l’élément sont évaluées.
  • Si vous êtes inscrit pour recevoir des notifications de modification de propriété sur la propriété contenant le ou les éléments différés, la notification est déclenchée.

Déchargement d’éléments

Pour décharger un élément :

  • Utilisez une expression x :Bind pour spécifier l’état de chargement. L’expression doit retourner true pour charger et false pour décharger l’élément.
  • Dans une page ou UserControl, appelez UnloadObject et transmettez la référence d’objet
  • Appeler Windows.UI.Xaml.Markup.XamlMarkupHelper.UnloadObject et passer la référence d’objet

Lorsqu’un objet est déchargé, il est remplacé dans l’arborescence par un espace réservé. L’instance d’objet reste en mémoire jusqu’à ce que toutes les références aient été libérées. L’API UnloadObject sur une page/UserControl est conçue pour libérer les références détenues par codegen pour x :Name et x :Bind. Si vous conservez des références supplémentaires dans le code de l’application, elles devront également être publiées.

Lorsqu’un élément est déchargé, tous les états associés à l’élément sont ignorés. Par conséquent, si vous utilisez x :Load comme version optimisée de Visibility, vérifiez que tout l’état est appliqué via des liaisons ou est réinitulé par le code lorsque l’événement Loaded est déclenché.

Restrictions

Les restrictions relatives à l’utilisation de x :Load sont les suivantes :

  • Vous devez définir un x :Name pour l’élément, car il doit y avoir un moyen de trouver l’élément ultérieurement.
  • Vous ne pouvez utiliser x :Load que sur les types qui dérivent d’UIElement ou de FlyoutBase.
  • Vous ne pouvez pas utiliser x :Load sur les éléments racines d’une page, d’un UserControl ou d’un DataTemplate.
  • Vous ne pouvez pas utiliser x :Load sur les éléments d’un ResourceDictionary.
  • Vous ne pouvez pas utiliser x :Load sur un xaml libre chargé avec XamlReader.Load.
  • Le déplacement d’un élément parent efface tous les éléments qui n’ont pas été chargés.

Notes

Vous pouvez utiliser x :Load sur des éléments imbriqués, mais ils doivent être réalisés à partir de l’élément le plus externe dans.  Si vous essayez de réaliser un élément enfant avant la réalisation du parent, une exception est levée.

En règle générale, nous vous recommandons de différer les éléments qui ne sont pas visibles dans le premier cadre. Une bonne directive pour trouver des candidats à différer consiste à rechercher les éléments qui sont créés avec une visibilité réduite. En outre, l’interface utilisateur déclenchée par l’interaction utilisateur est un bon endroit pour rechercher les éléments que vous pouvez différer.

Méfiez-vous des éléments différés dans un ListView, car il diminue le temps de démarrage, mais peut également diminuer vos performances de panoramique en fonction de ce que vous créez. Si vous envisagez d’augmenter les performances de panoramique, consultez la documentation sur l’extension de balisage {x :Bind} et la documentation sur les attributs x :Phase.

Si l’attribut x :Phase est utilisé conjointement avec x :Load, lorsqu’un élément ou une arborescence d’éléments est réalisé, les liaisons sont appliquées jusqu’à la phase actuelle et y compris. La phase spécifiée pour x :Phase affecte ou contrôle l’état de chargement de l’élément. Lorsqu’un élément de liste est recyclé dans le cadre d’un panoramique, les éléments réalisés se comportent de la même façon que d’autres éléments actifs et les liaisons compilées ({x :Bind} bindings) sont traitées à l’aide des mêmes règles, y compris la phase.

Une recommandation générale consiste à mesurer les performances de votre application avant et après pour vous assurer que vous obtenez les performances souhaitées.

Exemple

<StackPanel>
    <Grid x:Name="DeferredGrid" x:Load="False">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <Rectangle Height="100" Width="100" Fill="Orange" Margin="0,0,4,4"/>
        <Rectangle Height="100" Width="100" Fill="Green" Grid.Column="1" Margin="4,0,0,4"/>
        <Rectangle Height="100" Width="100" Fill="Blue" Grid.Row="1" Margin="0,4,4,0"/>
        <Rectangle Height="100" Width="100" Fill="Gold" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0"
                   x:Name="one" x:Load="{x:Bind (x:Boolean)CheckBox1.IsChecked, Mode=OneWay}"/>
        <Rectangle Height="100" Width="100" Fill="Silver" Grid.Row="1" Grid.Column="1" Margin="4,4,0,0"
                   x:Name="two" x:Load="{x:Bind Not(CheckBox1.IsChecked), Mode=OneWay}"/>
    </Grid>

    <Button Content="Load elements" Click="LoadElements_Click"/>
    <Button Content="Unload elements" Click="UnloadElements_Click"/>
    <CheckBox x:Name="CheckBox1" Content="Swap Elements" />
</StackPanel>
// This is used by the bindings between the rectangles and check box.
private bool Not(bool? value) { return !(value==true); }

private void LoadElements_Click(object sender, RoutedEventArgs e)
{
    // This will load the deferred grid, but not the nested
    // rectangles that have x:Load attributes.
    this.FindName("DeferredGrid"); 
}

private void UnloadElements_Click(object sender, RoutedEventArgs e)
{
     // This will unload the grid and all its child elements.
     this.UnloadObject(DeferredGrid);
}