x:Load-Attribut

Sie können x:Load verwenden, um den Start, die Visuelle Strukturerstellung und die Speicherauslastung Ihrer XAML-App zu optimieren. Die Verwendung von x:Load hat einen ähnlichen visuellen Effekt wie Visibility, mit der Ausnahme, dass, wenn das Element nicht geladen wird, sein Arbeitsspeicher freigegeben wird und intern ein kleiner Platzhalter verwendet wird, um seine Position in der visuellen Struktur zu markieren.

Das ui-Element, das x:Load zugeordnet ist, kann über Code oder mithilfe eines x:Bind-Ausdrucks geladen und entladen werden. Dies ist nützlich, um die Kosten von Elementen zu reduzieren, die selten oder bedingt angezeigt werden. Wenn Sie x:Load für einen Container wie Grid oder StackPanel verwenden, werden der Container und alle untergeordneten Elemente als Gruppe geladen oder entladen.

Die Nachverfolgung von verzögerten Elementen durch das XAML-Framework fügt der Speicherauslastung für jedes x:Load zugeordnete Element etwa 600 Bytes hinzu, um den Platzhalter zu berücksichtigen. Daher ist es möglich, dieses Attribut so weit zu verwenden, dass ihre Leistung tatsächlich abnimmt. Es wird empfohlen, sie nur für Elemente zu verwenden, die ausgeblendet werden müssen. Wenn Sie x:Load für einen Container verwenden, wird der Mehraufwand nur für das Element mit dem x:Load-Attribut bezahlt.

Wichtig

Das x:Load-Attribut ist ab Windows 10 Version 1703 (Creators Update) verfügbar. Die Mindestversion, auf die Ihr Visual Studio-Projekt abzielt, muss Windows 10 Creators Update (10.0, Build 15063) sein, damit „x:Load“ verwendet werden kann.

XAML-Attributsyntax

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

Laden von Elementen

Es gibt verschiedene Möglichkeiten, die Elemente zu laden:

  • Verwenden Sie einen x:Bind-Ausdruck , um den Ladezustand anzugeben. Der Ausdruck sollte true zurückgeben, um das Element zu laden, und false , um das Element zu entladen.
  • Rufen Sie FindName mit dem Namen auf, den Sie für das Element definiert haben.
  • Rufen Sie GetTemplateChild mit dem Namen auf, den Sie für das Element definiert haben.
  • Verwenden Sie in einem VisualState eine Setter- oder Storyboardanimation , die auf das x:Load-Element ausgerichtet ist.
  • Ziel des entladenen Elements in einem beliebigen Storyboard.

HINWEIS: Nach Start der Instanziierung eines Elements wird es im Benutzeroberflächen-Thread erstellt. Dies kann ggf. bewirken, dass die Oberfläche ruckelt, wenn zu viele auf einmal erstellt werden.

Sobald ein verzögertes Element auf eine der zuvor aufgeführten Arten erstellt wurde, geschieht folgendes:

  • Das Loaded-Ereignis für das -Element wird ausgelöst.
  • Das Feld für x:Name ist festgelegt.
  • Alle x:Bind-Bindungen für das Element werden ausgewertet.
  • Wenn Sie sich für den Empfang von Eigenschaftsänderungsbenachrichtigungen für die Eigenschaft registriert haben, die die verzögerten Elemente enthält, wird die Benachrichtigung ausgelöst.

Entladen von Elementen

So entladen Sie ein Element:

  • Verwenden Sie einen x:Bind-Ausdruck, um den Ladezustand anzugeben. Der Ausdruck sollte true zurückgeben, um das Element zu laden, und false , um das Element zu entladen.
  • Rufen Sie in einem Page- oder UserControl-Objekt UnloadObject auf, und übergeben Sie den Objektverweis.
  • Aufrufen von Windows.UI.Xaml.Markup.XamlMarkupHelper.UnloadObject und Übergeben des Objektverweis

Wenn ein Objekt entladen wird, wird es in der Struktur durch einen Platzhalter ersetzt. Das Objekt instance verbleibt im Arbeitsspeicher, bis alle Verweise freigegeben wurden. Die UnloadObject-API für ein Page/UserControl-Objekt wurde entwickelt, um die Verweise freizugeben, die von codegen für x:Name und x:Bind gespeichert sind. Wenn Sie zusätzliche Verweise im App-Code enthalten, müssen diese ebenfalls freigegeben werden.

Wenn ein Element entladen wird, wird der gesamte Zustand, der dem Element zugeordnet ist, verworfen. Wenn Sie also x:Load als optimierte Version von Visibility verwenden, stellen Sie sicher, dass der gesamte Zustand über Bindungen angewendet wird oder vom Code erneut angewendet wird, wenn das Loaded-Ereignis ausgelöst wird.

Beschränkungen

Die Einschränkungen für die Verwendung von x:Load sind:

  • Sie müssen einen x:Name für das Element definieren, da es eine Möglichkeit geben muss, das Element später zu finden.
  • Sie können x:Load nur für Typen verwenden, die von UIElement oder FlyoutBase abgeleitet sind.
  • Sie können x:Load nicht für Stammelemente in einer Seite, einem UserControl oder einer DataTemplate verwenden.
  • Sie können x:Load nicht für Elemente in einem ResourceDictionary verwenden.
  • Sie können x:Load nicht für lose XAML verwenden, die mit XamlReader.Load geladen wurde.
  • Wenn Sie ein übergeordnetes Element verschieben, werden alle Elemente gelöscht, die nicht geladen wurden.

Hinweise

Sie können x:Load für geschachtelte Elemente verwenden, sie müssen jedoch aus dem äußersten Element in realisiert werden.  Wenn Sie versuchen, ein untergeordnetes Element zu erkennen, bevor das übergeordnete Element realisiert wurde, wird eine Ausnahme ausgelöst.

In der Regel wird empfohlen, Elemente zurückstellen, die im ersten Frame nicht sichtbar sind. Bei der Suche nach zu verzögernden Kandidaten empfiehlt es sich, nach Elementen zu suchen, die mit reduzierter Visibility erstellt werden. Außerdem ist die Benutzeroberfläche, die durch Benutzerinteraktionen ausgelöst wird, ein guter Ort, um nach Elementen zu suchen, die Sie zurückstellen können.

Seien Sie vorsichtig, wenn Sie Elemente in einer ListView zurückstellen, da dies die Startzeit verringert, aber auch die Verschiebungsleistung je nach Dem, was Sie erstellen, beeinträchtigen kann. Wenn Sie die Verschiebungsleistung erhöhen möchten, lesen Sie die { x:Bind}-Markuperweiterung und die Dokumentation zu x:Phase-Attributen .

Wenn das x:Phase-Attribut in Verbindung mit x:Load verwendet wird, werden die Bindungen bis einschließlich der aktuellen Phase angewendet, wenn ein Element oder eine Elementstruktur realisiert wird. Die für x:Phase angegebene Phase wirkt sich auf den Ladezustand des Elements aus oder steuert diese. Wenn ein Listenelement im Rahmen der Verschiebung wiederverwendet wird, verhalten sich realisierte Elemente auf die gleiche Weise wie andere aktive Elemente, und kompilierte Bindungen ({x:Bind}- Bindungen) werden mit den gleichen Regeln verarbeitet, einschließlich Phasing.

Eine allgemeine Richtlinie besteht darin, die Leistung Ihrer App vorher und nach zu messen, um sicherzustellen, dass Sie die gewünschte Leistung erhalten.

Beispiel

<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);
}