x:Load-Attribut
Sie können "x:Load" verwenden, um den Start, die visuelle Strukturerstellung und die Speichernutzung Ihrer XAML-App zu optimieren. Die Verwendung von "x:Load" hat einen ähnlichen visuellen Effekt wie Visibility. Wenn das Element nicht geladen wird, wird der Speicher freigegeben, und intern wird ein kleiner Platzhalter verwendet, um seine Position in der visuellen Struktur zu markieren.
Das ui-Element, das x:Load zugeordnet ist, kann über Code geladen und entladen werden oder einen x:Bind-Ausdruck verwenden. Dies ist hilfreich, um die Kosten für Elemente 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 verzögerter Elemente durch das XAML-Framework fügt etwa 600 Byte zur Speicherauslastung für jedes Element hinzu, das x:Load zugeordnet ist, um den Platzhalter zu berücksichtigen. Daher ist es möglich, dieses Attribut zu überlasten, soweit die Leistung tatsächlich verringert wird. 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 Aufwand 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 zum Laden der Elemente:
- 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-Element eine Setter- oder Storyboardanimation, die auf das x:Load-Element ausgerichtet ist.
- Richten Sie das entladene Element in einem beliebigen Storyboard an.
HINWEIS: Sobald die Instanziierung eines Elements gestartet wurde, wird es im UI-Thread erstellt, sodass die Benutzeroberfläche stottern kann, wenn zu viel gleichzeitig erstellt wird.
Sobald ein verzögertes Element auf eine der zuvor aufgeführten Arten erstellt wurde, passieren mehrere Dinge:
- 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 angewendet.
- Wenn Sie für den Empfang von Eigenschaftsänderungsbenachrichtigungen für die Eigenschaft registriert haben, die das verzögerte Element(n) 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 einer Page oder UserControl UnloadObject auf, und übergeben Sie den Objektverweis.
- Rufen Sie "Windows.UI.Xaml.Markup.XamlMarkupHelper.UnloadObject " auf, und übergeben Sie das Objektverweis.
Wenn ein Objekt entladen wird, wird es in der Struktur durch einen Platzhalter ersetzt. Die Objektinstanz verbleibt im Arbeitsspeicher, bis alle Verweise freigegeben wurden. Die UnloadObject-API auf einer Seite/UserControl wurde entwickelt, um die Verweise freizugeben, die von Codegen für x:Name und x:Bind gehalten werden. Wenn Sie zusätzliche Verweise im App-Code enthalten, müssen sie ebenfalls freigegeben werden.
Wenn ein Element entladen wird, werden alle dem Element zugeordneten Zustände verworfen. Wenn Sie also x:Load als optimierte Version von Sichtbarkeit verwenden, stellen Sie sicher, dass der gesamte Zustand über Bindungen angewendet wird oder durch 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 on" für Elemente in einem ResourceDictionary nicht verwenden.
- Sie können "x:Load" nicht für lose XAML verwenden, das mit XamlReader.Load geladen wurde.
- Durch das Verschieben eines übergeordneten Elements werden alle Elemente gelöscht, die nicht geladen wurden.
Hinweise
Sie können "x:Load" für geschachtelte Elemente verwenden, müssen jedoch aus dem äußersten Element realisiert werden. Wenn Sie versuchen, ein untergeordnetes Element zu erkennen, bevor das übergeordnete Element erkannt wurde, wird eine Ausnahme ausgelöst.
In der Regel wird empfohlen, Elemente zurückstellen, die im ersten Frame nicht angezeigt werden können. Eine gute Richtlinie für das Auffinden von Kandidaten, die zurückgestellt werden sollen, besteht darin, nach Elementen zu suchen, die mit reduzierter Sichtbarkeit erstellt werden. Darüber hinaus ist die Benutzeroberfläche, die von der Benutzerinteraktion ausgelöst wird, ein guter Ort, um nach Elementen zu suchen, die Sie zurückstellen können.
Seien Sie vorsichtig beim Zurückstellen von Elementen in einer ListView, da sie die Startzeit verringert, aber auch die Leistung beim Verschieben verringern könnte, je nachdem, was Sie erstellen. Wenn Sie die Verschiebungsleistung erhöhen möchten, lesen Sie die Dokumentation zur {x:Bind}-Markuperweiterung und zum x:Phase-Attribut .
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 sie. Wenn ein Listenelement als Teil 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 nachher zu messen, um sicherzustellen, dass Sie die gewünschte Leistung erhalten.
Um Änderungen des Verhaltens (abgesehen von der Leistung) beim Hinzufügen von x:Load zu einem Element zu minimieren, werden x:Bind-Bindungen zu ihren normalen Zeiten berechnet, als ob keine Elemente x:Load verwendet haben. Beispielsweise werden OneTime x:Bind-Bindungen berechnet, wenn das Stammelement geladen wird. Wenn das Element zum Zeitpunkt der Berechnung der x:Bind-Bindung nicht realisiert wird, wird der berechnete Wert gespeichert und beim Laden auf das Element angewendet. Dieses Verhalten kann überraschend sein, wenn Sie erwartet haben, dass x:Bind-Bindungen berechnet werden, wenn das Element realisiert wird.
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);
}