次の方法で共有


x:Load 属性

x:Load を使用して、XAML アプリのスタートアップ、ビジュアル ツリーの作成、メモリ使用量を最適化できます。 x:Load を使用すると、要素が読み込まれていない場合、可視性と同様の視覚効果がありますが、メモリが解放されます。そして、内部的には小さなプレースホルダーが使用され、その場所がビジュアルツリー内でマークされます。

x:Load に属性付けされた UI 要素は、コードを使用するか、 x:Bind 式を使用して読み込んだりアンロードしたりすることができます。 これは、表示頻度が低い要素や条件付き要素のコストを削減するのに役立ちます。 Grid や StackPanel などのコンテナーで x:Load を使用すると、コンテナーとそのすべての子がグループとして読み込まれるかアンロードされます。

XAML フレームワークによる遅延要素の追跡では、プレースホルダーを考慮して、x:Load で属性付けされた各要素のメモリ使用量に約 600 バイトが追加されます。 そのため、パフォーマンスが実際に低下する程度に、この属性を過剰に使用する可能性があります。 非表示にする必要がある要素でのみ使用することをお勧めします。 コンテナーで x:Load を使用する場合、オーバーヘッドは x:Load 属性を持つ要素に対してのみ支払われます。

Important

x:Load 属性は、Windows 10 バージョン 1703 (Creators Update) 以降で使用できます。 x:Load を使用するには、Visual Studio プロジェクトの対象となる最小バージョンが Windows 10 Creators Update (10.0、ビルド 15063) である必要があります。

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 要素を対象とするセッターアニメーションまたはストーリーボード アニメーションを使用します。
  • ストーリーボード内のアンロードされた要素をターゲットにします。

要素のインスタンス化が開始されると、その要素は UI スレッド上に作成されるため、一度に作成した数が多すぎると UI が途切れる可能性があります。

前に示した方法のいずれかで遅延要素が作成されると、いくつかの処理が行われます。

  • 要素の Loaded イベントが発生します。
  • x:Name のフィールドが設定されています。
  • 要素の x:Bind バインドが適用されます。
  • 遅延要素を含むプロパティのプロパティ変更通知を受信するように登録している場合は、通知が発生します。

要素のアンロード

要素をアンロードするには:

  • x:Bind 式を使用して、読み込み状態を指定します。 式は読み込むには true を返し、要素をアンロードするには false を返す必要があります。
  • Page または UserControl で UnloadObject を呼び出し、オブジェクト参照を渡します
  • Microsoft.UI.Xaml.Markup.XamlMarkupHelper.UnloadObject を呼び出し、オブジェクト参照を渡します

オブジェクトがアンロードされると、ツリー内でプレースホルダーに置き換えられます。 オブジェクト インスタンスは、すべての参照が解放されるまでメモリ内に残ります。 Page/UserControl の UnloadObject API は、x:Name と x:Bind の codegen によって保持されている参照を解放するように設計されています。 アプリ コードに追加の参照を保持する場合は、リリースする必要もあります。

要素がアンロードされると、要素に関連付けられているすべての状態が破棄されるため、最適化されたバージョンの Visibility として x:Load を使用する場合は、バインドによってすべての状態が適用されるか、Loaded イベントが発生したときにコードによって再適用されることを確認します。

制約

x:Load の使用に関する制限事項は次のとおりです。

  • 後で要素を検索する方法が必要な場合は、要素の x:Name を定義する必要があります。
  • UIElement または FlyoutBase から派生した型でのみ x:Load を使用できます。
  • ページ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 バインドが計算されることが予想される場合は、驚くことがあります。

Example

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