x:Load 屬性
您可以使用 x:Load 來最佳化 XAML 應用程式的啟動、視覺化樹狀結構建立和記憶體使用量。 使用 x:Load 具有與 Visibility 類似的視覺效果,只不過當元素未載入時,其記憶體將被釋放,並且內部使用小預留位置來標記其在視覺化樹狀結構中的位置。
使用 x:Load 屬性的 UI 元素可以透過程式碼載入和卸載,或使用 x:Bind 運算式。 這對於降低不常或有條件地顯示的元素成本很有用。 當您在 Grid 或 StackPanel 等容器上使用 x:Load 時,容器及其所有下層都會以群組的形式載入或卸載。
XAML 架構的延遲元素追蹤會將大約 600 個位元組新增至以 x:Load 屬性設定的每個元素的記憶體使用量,以考慮預留位置。 因此,過度使用此屬性可能會導致您的效能實際下降。 我們建議您只在需要隱藏的元素上使用它。 如果您在容器上使用 x:Load,則只會針對具有 x:Load 屬性的元素支付額外負荷。
重要
x:Load 屬性從 Windows 10 版本 1703 (Creators Update) 開始可用。 Visual Studio 專案設為目標的版本必須至少是 Windows 10 Creators Update (10.0,組建 15063),才能使用 x:Load。
XAML 屬性用法
<object x:Load="True" .../>
<object x:Load="False" .../>
<object x:Load="{x:Bind Path.to.a.boolean, Mode=OneWay}" .../>
載入元素
有幾種不同的方式來載入元素:
- 使用 x:Bind 運算式來指定載入狀態。 運算式應該傳回 true 以載入和傳回 false 來卸載元素。
- 使用您在元素上定義的名稱呼叫 FindName。
- 使用您在元素上定義的名稱呼叫 GetTemplateChild。
- 在 VisualState 中,使用針對 x:Load 元素的 Setter 或 Storyboard 動畫。
- 將任何分鏡腳本中的卸載元素做為目標。
注意:一旦元素的具現化啟動,就會在 UI 執行緒上建立它,因此,如果一次建立太多,它可能會導致 UI 變得卡頓。
一旦以先前所列的任何方式建立延遲元素,就會發生數件事:
- 引發元素上的已載入事件。
- 已設定 x:Name 的欄位。
- 套用元素上的任何 x:Bind 系結。
- 如果您已註冊以在包含延遲元素的屬性上接收屬性變更通知,則會引發通知。
卸載元素
若要卸載元素:
- 使用 x:Bind 運算式來指定載入狀態。 運算式應該傳回 true 以載入和傳回 false 來卸載元素。
- 在 Page 或 UserControl 中,呼叫 UnloadObject 並傳入物件參考
- 呼叫 Windows.UI.Xaml.Markup.XamlMarkupHelper.UnloadObject 並傳入物件參考
卸載物件時,它會在樹狀結構中取代為預留位置。 物件執行個體會保留在記憶體中,直到釋放所有參考為止。 Page/UserControl 上的 UnloadObject API 旨在釋放 codegen 所保留的 x:Name 和 x:Bind 參考。 如果您在應用程式程式碼中保留其他參考,則也需要釋放這些參考。
卸載元素時,將會捨棄與元素相關聯的所有狀態,因此如果使用 x:Load 做為 Visibility 的最佳化版本,則請確定所有狀態都是透過繫結套用,或在引發 Loaded 事件時由程式碼重新套用。
限制
使用 x:Load 的限制是:
- 您必須為該元素定義一個 x:Name,因為稍後需要有一種方法來尋找該元素。
- 您只能在從 UIElement 或 FlyoutBase 衍生的類型上使用 x:Load。
- 您不能在 Page、UserControl 或 DataTemplate 中的根元素上使用 x:Load。
- 您無法在 ResourceDictionary 中的元素上使用 x:Load。
- 您無法在以 XamlReader.Load 載入的鬆散 XAML 上使用 x:Load。
- 移動上層元素將會清除任何尚未載入的元素。
備註
您可以在巢狀元素上使用 x:Load,但是它們必須從最外層元素中實作。 如果您嘗試在上層元素實現之前實現下層元素,則會引發例外狀況。
一般而言,建議您延遲無法在第一個畫面中檢視的元素。 尋找要推遲的候選項目的一個很好的指導方針,是尋找使用折疊可見度建立的元素。 此外,使用者互動所觸發的 UI 是尋找您可以延遲之元素的好位置。
請小心延遲 ListView 中的元素,因為它會減少啟動時間,但也可能降低平移效能,這取決於您所建立的內容。 如果您希望提高平移效能,請參閱 {x:Bind} 標記延伸和 x:Phase 屬性文件。
如果 x:Phase 屬性與 x:Load 結合使用,那麼當實作元素或元素樹狀結構時,繫結將會套用到目前階段 (包括目前階段)。 為 x:Phase 指定的階段確實會影響或控制元素的載入狀態。 當清單項目做為平移的一部分被回收時,已實現的元素將以與其他使用中元素相同的方式運作,並且已編譯的繫結 ({x:Bind} 繫結) 將使用相同的規則 (包括分階段) 進行處理。
一般指導方針是測量您應用程式前後的效能,以確保您取得所需的效能。
若要將 x:Load 新增至專案時的行為變更降到最低,x:Bind 系結會在正常時間計算,就像沒有使用 x:Load 的項目一樣。 例如,當根元素載入時,會計算 OneTime x:Bind 系結。 如果在計算 x:Bind 系結時未實現專案,則會在載入時儲存匯出值並套用至專案。 如果您預期 元素實現時要計算 x:Bind 系結,此行為可能會出人意料。
範例
<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);
}