ItemsRepeaterItemsRepeater

柔軟なレイアウト システム、カスタム ビュー、および仮想化を使ってカスタム コレクション エクスペリエンスを作成するには、ItemsRepeater を使用します。Use an ItemsRepeater to create custom collection experiences using a flexible layout system, custom views, and virtualization.

ListView とは異なり、ItemsRepeater では包括的なエンド ユーザー エクスペリエンスが提供されません。既定の UI はなく、フォーカス、選択、ユーザーの操作に関するポリシーは提供されません。Unlike ListView, ItemsRepeater does not provide a comprehensive end-user experience – it has no default UI and provides no policy around focus, selection, or user interaction. その代わり、構成要素を使用することで、独自の一意のコレクション ベースのエクスペリエンスおよびカスタム コントロールを作成することができます。Instead, it’s a building block that you can use to create your own unique collection-based experiences and custom controls. 組み込みのポリシーはありませんが、必要なエクスペリエンスを構築するためのポリシーをアタッチすることができます。While it has no built-in policy, it enables you to attach policy to build the experience you require. たとえば、使用するレイアウト、キーボード操作ポリシー、選択ポリシーなどを定義できます。For example, you can define the layout to use, the keyboarding policy, the selection policy, etc.

ItemsRepeater は概念的に、ListView などの完全なコントロールとしてではなく、データドリブン パネルと考えることができます。You can think of ItemsRepeater conceptually as a data-driven panel, rather than as a complete control like ListView. 表示されるデータ項目のコレクション、各データ項目の UI 要素を生成する項目テンプレート、要素のサイズと位置を設定する方法を決定するレイアウトを指定します。You specify a collection of data items to be displayed, an item template that generates a UI element for each data item, and a layout that determines how the elements are sized and positioned. その後、ItemsRepeater でデータ ソースに基づいた子要素が生成され、項目テンプレートとレイアウトで指定されたとおりに表示されます。Then, ItemsRepeater produces child elements based on the data source, and displays them as specified by the item template and layout. 表示される項目が同種である必要はありません。これは、データ テンプレート セレクターで指定する条件に基づいてデータ項目を表すために、ItemsRepeater でコンテンツを読み込むことができるためです。The items displayed do not need to be homogenous because ItemsRepeater can load content to represent the data items based on criteria you specify in a data template selector.

Windows UI ライブラリを入手するGet the Windows UI Library
このコントロールは、Windows UI ライブラリの NuGet パッケージの一部として組み込まれており、パッケージには、UWP アプリの新しいコントロールと UI 機能が含まれています。This control is included as part of the Windows UI Library, a NuGet package that contains new controls and UI features for UWP apps. インストール手順などの詳細については、Windows UI ライブラリの概要に関するページを参照してください。For more info, including installation instructions, see the Windows UI Library overview.

重要な API:ItemsRepeater クラスScrollViewer クラスImportant APIs: ItemsRepeater class, ScrollViewer class

適切なコントロールの選択Is this the right control?

データ コレクション用のカスタム表示を作成するには、ItemsRepeater を使用します。Use an ItemsRepeater to create custom displays for collections of data. これは基本的な一連の項目を表示するために使用できますが、多くの場合、カスタム コントロールのテンプレートで表示要素として使用します。While it can be used to present a basic set of items, you might often use it as the display element in the template of a custom control.

最小限にカスタマイズされたグリッドまたはリストにデータを表示するためにすぐに使えるコントロールが必要な場合は、ListView または GridView の使用を検討してください。If you need an out-of-the-box control to display data in a list or grid with minimal customization, consider using a ListView or GridView.

ItemsRepeater には組み込みの項目コレクションはありません。ItemsRepeater does not have a built-in Items collection. 別のデータ ソースにバインドするのではなく、項目コレクションを直接提供しなければならない場合は、より高いポリシー エクスペリエンスが必要になる可能性があり、ListView または GridView を使用する必要があります。If you need to provide an Items collection directly, rather than binding to a separate data source, then you're likely in need of a more high-policy experience and should use ListView or GridView.

ItemsControl と ItemsRepeater の両方でカスタマイズ可能なコレクション エクスペリエンスを有効にすることはできますが、ItemsRepeater では UI レイアウトの仮想化がサポートされるのに対して ItemsControl ではサポートされません。ItemsControl and ItemsRepeater both enable customizable collection experiences, but ItemsRepeater supports virtualizing UI layouts, while ItemsControl does not. 単にデータのいくつかの項目を表示するためであるか、カスタム コレクション コントロールをビルドするためであるかに関係なく、ItemsControl ではなく ItemsRepeater を使用することをお勧めします。We recommend using ItemsRepeater instead of ItemsControl, whether its for just presenting a few items from data or building a custom collection control.

注意

ItemsControl ではニーズが満たされ、ItemsRepeater では満たされていないと思われる場合は、Windows UI ライブラリの GitHub プロジェクトでフィードバックを送信してお知らせください。If you have a situation where you feel ItemsControl meets your needs and ItemsRepeater doesn't, please leave feedback on the Windows UI Library GitHub project and let us know.

Examples

XAML コントロール ギャラリーXAML Controls Gallery
XAML controls gallery

XAML コントロール ギャラリー アプリがインストールされている場合は、こちらをクリックしてアプリを開き、ItemsRepeater の動作を確認してください。If you have the XAML Controls Gallery app installed, click here to open the app and see the ItemsRepeater in action.

ItemsRepeater でのスクロールScrolling with ItemsRepeater

ItemsRepeaterControl から派生しないため、コントロール テンプレートはありません。ItemsRepeater does not derive from Control, so it doesn't have a control template. したがって、ListView やその他のコレクション コントロールのようにスクロールの操作は組み込まれていません。Therefore, it doesn't contain any built-in scrolling like a ListView or other collection controls do.

ItemsRepeater を使用する場合は、ScrollViewer コントロールでラップし、スクロール機能を提供する必要があります。When you use an ItemsRepeater, you should provide scrolling functionality by wrapping it in a ScrollViewer control.

注意

以前のバージョンの Windows (Windows 10 バージョン 1809 より前 にリリースされたもの) でアプリを実行する場合は、ItemsRepeaterScrollHost 内で ScrollViewer をホストする必要もあります。If your app will run on earlier versions of Windows - those released before Windows 10, version 1809 - then you also need to host the ScrollViewer inside the ItemsRepeaterScrollHost.

<muxc:ItemsRepeaterScrollHost>
    <ScrollViewer>
        <muxc:ItemsRepeater ... />
    </ScrollViewer>
</muxc:ItemsRepeaterScrollHost>

最新バージョン (バージョン 1809 以降) の Windows 10 でのみアプリを実行する場合は、ItemsRepeaterScrollHost を使用する必要はありません。If your app will only run on recent versions of Windows 10, version 1809 and later - then there is no need to use the ItemsRepeaterScrollHost.

Windows 10 バージョン 1809 より前の場合、ScrollViewer では、ItemsRepeater に必要な IScrollAnchorProvider インターフェイスが実装されませんでした。Prior to Windows 10, version 1809, ScrollViewer did not implement the IScrollAnchorProvider interface that the ItemsRepeater needs. ItemsRepeaterScrollHost では、ItemsRepeater が以前のリリースの ScrollViewer と連動し、ユーザーに表示される項目の見える場所が適切に保持されるようにします。The ItemsRepeaterScrollHost enables the ItemsRepeater to coordinate with ScrollViewer on earlier releases to correctly preserve the visible location of items the user is viewing. それ以外の場合、リスト内の項目が変更されたり、アプリのサイズが変更されたりした場合に、項目が突然移動されたり、消されたりするように表示されることがあります。Otherwise, the items might appear to move or disappear suddenly when the items in the list are changed or the app is resized.

ItemsRepeater を作成するCreate an ItemsRepeater

ItemsRepeater を使用するには、ItemsSource プロパティを設定し、表示するデータを指定する必要があります。To use an ItemsRepeater, you need to give it the data to display by setting the ItemsSource property. その後、ItemTemplate プロパティを設定し、項目の表示方法を指示します。Then, tell it how to display the items by setting the ItemTemplate property.

ItemsSourceItemsSource

ビューを設定するには、ItemsSource プロパティをデータ項目のコレクションに設定します。To populate the view, set the ItemsSource property to a collection of data items. ここでは、ItemsSource がコードでコレクションのインスタンスに直接設定されています。Here, the ItemsSource is set in code directly to an instance of a collection.

ObservableCollection<string> Items = new ObservableCollection<string>();

ItemsRepeater itemsRepeater1 = new ItemsRepeater();
itemsRepeater1.ItemsSource = Items;

ItemsSource プロパティを、XAML でコレクションにバインドすることもできます。You can also bind the ItemsSource property to a collection in XAML. データ バインディングについて詳しくは、「データ バインディングの概要」をご覧ください。For more info about data binding, see Data binding overview.

<ItemsRepeater ItemsSource="{x:Bind Items}"/>

ItemTemplateItemTemplate

データ項目を視覚化する方法を指定するには、定義した DataTemplate または DataTemplateSelectorItemTemplate プロパティを設定します。To specify how a data item is visualized, set the ItemTemplate property to a DataTemplate or DataTemplateSelector you have defined. データ テンプレートで、データがどのように視覚化されるかが定義されます。The data template defines how the data is visualized. 既定では、項目は、データ オブジェクトの文字列表現を使用する TextBlock でビューに表示されます。By default, the item is displayed in the view with a TextBlock the uses the string representation of the data object.

しかし、通常は、個々の項目を表示するために使用する 1 つまたは複数のコントロールのレイアウトと外観を定義するテンプレートを使用して、より豊富な表現でデータを表示する必要があります。However, you typically want to show a more rich presentation of your data by using a template that defines the layout and appearance of one or more controls that you'll use to display an individual item. テンプレートで使用するコントロールを、データ オブジェクトのプロパティにバインドすることも、その静的コンテンツをインラインで定義することもできます。The controls you use in the template can be bound to the properties of the data object, or have static content defined inline.

DataTemplateDataTemplate

この例では、データ オブジェクトはシンプルな文字列です。In this example, the data object is a simple string. DataTemplate にはテキストの左側にイメージが含まれており、青緑色で文字列を表示するために TextBlock がスタイル設定されています。The DataTemplate includes an image to the left of the text, and styles the TextBlock to display the string in a teal color.

注意

DataTemplatex:Bind markup extension を使う場合、DataTemplate に DataType (x:DataType) を指定する必要があります。When you use the x:Bind markup extension in a DataTemplate, you have to specify the DataType (x:DataType) on the DataTemplate.

<DataTemplate x:DataType="x:String">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="47"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Image Source="Assets/placeholder.png" Width="32" Height="32"
               HorizontalAlignment="Left"/>
        <TextBlock Text="{x:Bind}" Foreground="Teal"
                   FontSize="15" Grid.Column="1"/>
    </Grid>
</DataTemplate>

この DataTemplate で項目を表示した場合、次のようになります。Here's how the items would appear when displayed with this DataTemplate.

データ テンプレートを使って表示された項目

ビューで多くの項目が表示される場合、項目の DataTemplate で使用される要素の数がパフォーマンスに大きく影響する可能性があります。The number of elements used in the DataTemplate for an item can have a significant impact on performance if your view displays a large number of items. DataTemplate を使用してリスト項目の外観を定義する詳しい方法のその例については、「項目のコンテナーとテンプレート」を参照してください。For more info and examples of how to use DataTemplates to define the look of items in your list, see Item containers and templates.

ヒント

便宜上、静的リソースとして参照するのではなく、テンプレートをインラインで宣言する必要がある場合は、ItemsRepeater の直接の子として、DataTemplate または DataTemplateSelector を指定することができます。For convenience when you want to declare the template inline rather than referenced as a static resource, you can specify the DataTemplate or DataTemplateSelector as the direct child of the ItemsRepeater. これは、ItemTemplate プロパティの値として割り当てられます。It will be assigned as the value of the ItemTemplate property. たとえば、これが有効です。For example, this is valid:

<ItemsRepeater ItemsSource="{x:Bind Items}">
    <DataTemplate>
        <!-- ... -->
    </DataTemplate>
</ItemsRepeater>

ヒント

ListView やその他のコレクション コントロールとは異なり、ItemsRepeater では、余白、パディング、選択ビジュアル、ビジュアル状態のポインターなど、既定のポリシーを含む追加の項目コンテナーがある DataTemplate の要素は折り返されません。Unlike ListView and other collection controls, the ItemsRepeater doesn't wrap the elements from a DataTemplate with an additional item container that includes default policy such as margins, padding, selection visuals, or a pointer over visual state. 代わりに、ItemsRepeater では、DataTemplate で定義された内容のみが表示されます。Instead, ItemsRepeater only presents what is defined in the DataTemplate. 項目をリスト ビュー項目と同じ外観にする必要がある場合は、データ テンプレートで、ListViewItem などの、コンテナーを明示的に含めることができます。If you want your items to have the same look as a list view item, you can explicitly include a container, like ListViewItem, in your data template. ItemsRepeater では ListViewItem ビジュアルが表示されますが、選択や複数選択チェックボックスの表示など、その他の機能は自動的に利用されません。ItemsRepeater will show the ListViewItem visuals, but doesn't automatically make use of other functionality, like selection or showing the multi-select checkbox.

同様に、データ コレクションが、Button (List<Button>) などの、実際のコントロールのコレクションである場合は、DataTemplateContentPresenter を配置してコントロールを表示することができます。Similarly, if your data collection is a collection of actual controls, like Button (List<Button>), you can put a ContentPresenter in your DataTemplate to display the control.

DataTemplateSelectorDataTemplateSelector

ビューで表示する項目が、同じ種類である必要はありません。The items you display in your view do not need to be of the same type. DataTemplateSelector を使用して ItemTemplate プロパティを指定し、指定した条件に基づいて異なる DataTemplate を選択することができます。You can provide the ItemTemplate property with a DataTemplateSelector to select different DataTemplates based on criteria you specify.

この例では、Large と Small の項目を表すために、2 つの異なる DataTemplate のうちどちらかを決める DataTemplateSelector が定義されていると仮定します。This example assumes a DataTemplateSelector has been defined that decides between two different DataTemplates to represent a Large and Small item.

<ItemsRepeater ...>
    <ItemsRepeater.ItemTemplate>
        <local:VariableSizeTemplateSelector Large="{StaticResource LargeItemTemplate}" 
                                            Small="{StaticResource SmallItemTemplate}"/>
    </ItemsRepeater.ItemTemplate>
</ItemsRepeater>

ItemsRepeater で使用する DataTemplateSelector を定義する場合、SelectTemplateCore(Object) メソッドのオーバーライドを実装するだけで済みます。When defining a DataTemplateSelector to use with ItemsRepeater you only need to implement an override for the SelectTemplateCore(Object) method. 詳しい説明と例については、DataTemplateSelector に関するページを参照してください。For more info and examples, see DataTemplateSelector.

注意

より高度なシナリオで要素を作成する方法を管理する DataTemplate の代わりに、独自の Windows.UI.Xaml.Controls.IElementFactory を実装し、ItemTemplate として使用することができます。An alternative to DataTemplates to manage how elements are created in more advanced scenarios is to implement your own Windows.UI.Xaml.Controls.IElementFactory to use as the ItemTemplate. これには、要求されたときにコンテンツを生成する役割があります。It will be responsible for generating content when requested.

データ ソースを構成するConfigure the data source

項目のコンテンツを生成するために使用するコレクションを指定するには、ItemsSource プロパティを使用します。Use the ItemsSource property to specify the collection to use to generate the content of items. IEnumerable を実装する任意の種類に ItemsSource を設定することができます。You can set the ItemsSource to any type that implements IEnumerable. データ ソースによって実装される追加のコレクション インターフェイスで、データを操作するために ItemsRepeater で使用できる機能が決定されます。Additional collection interfaces implemented by your data source determine what functionality is available to the ItemsRepeater to interact with your data.

このリストには使用可能なインターフェイスと、それぞれの使用を検討するタイミングが示されています。This list shows available interfaces and when to consider using each one.

  • IEnumerable(.NET) / IIterableIEnumerable(.NET) / IIterable

    • 小規模の静的なデータ セットで使用できます。Can be used for small, static data sets.

      データ ソースでは、少なくとも IEnumerable / IIterable インターフェイスを実装する必要があります。At a minimum, the data source must implement the IEnumerable / IIterable interface. サポートされているのがこれだけである場合、コントロールで一度すべてのものが反復処理されると、インデックス値を使用して項目にアクセスするために使用できるコピーが作成されます。If this is all that's supported then the control will iterate through everything once to create a copy that it can use to access items via an index value.

  • IReadonlyList(.NET) / IVectorViewIReadonlyList(.NET) / IVectorView

    • 静的な読み取り専用のデータ セットで使用できます。Can be used for static, read-only data sets.

      インデックスを使用してコントロールで項目にアクセスできるようにし、内部の冗長コピーの回避を可能にします。Enables the control to access items by index and avoids the redundant internal copy.

  • IList(.NET) / IVectorIList(.NET) / IVector

    • 静的なデータ セットで使用できます。Can be used for static data sets.

      インデックスを使用してコントロールで項目にアクセスできるようにし、内部の冗長コピーの回避を可能にします。Enables the control to access items by index and avoids the redundant internal copy.

      警告:INotifyCollectionChanged を実装せずに list/vector を変更した場合、UI では反映されません。Warning: Changes to the list/vector without implementing INotifyCollectionChanged won't be reflected in the UI.

  • INotifyCollectionChanged(.NET)INotifyCollectionChanged(.NET)

    • 変更通知をサポートすることをお勧めします。Recommended to support change notification.

      コントロールで、データ ソース内の変更を監視して対応できるようにし、これらの変更を UI に反映できるようにします。Enables the control to observe and react to changes in the data source and reflect those changes in the UI.

  • IObservableVectorIObservableVector

    • 変更通知がサポートされますSupports change notification

      INotifyCollectionChanged インターフェイスと同様、これにより、コントロールでデータ ソース内の変更を監視し、対応できるようになります。Like the INotifyCollectionChanged interface, this enables the control to observe and react to changes in the data source.

      警告:Windows.Foundation.IObservableVector<T> では '移動' アクションはサポートされません。Warning: The Windows.Foundation.IObservableVector<T> doesn’t support a 'Move' action. そのため、UI で項目の表示状態が失われる可能性があります。This can cause the UI for an item to lose its visual state. たとえば、現在選択されているか、'削除' の後、'追加' によって移動が行われた場所にフォーカスがあるか、あるいはその両方の状態の項目のフォーカスが失われ、選択できなくなります。For example, an item that is currently selected and/or has focus where the move is achieved by a ‘Remove’ followed by an ‘Add’ will lose focus and no longer be selected.

      Platform.Collections.Vector<T> では IObservableVector<T> が使用され、これと同じ制限があります。The Platform.Collections.Vector<T> uses IObservableVector<T> and has this same limitation. '移動' アクションのサポートが必要な場合は、INotifyCollectionChanged インターフェイスを使用します。If support for a 'Move' action is required then use the INotifyCollectionChanged interface. .NET ObservableCollection<T> クラスでは INotifyCollectionChanged が使用されます。The .NET ObservableCollection<T> class uses INotifyCollectionChanged.

  • IKeyIndexMappingIKeyIndexMapping

    • 一意識別子を各項目に関連付けることができる場合。When a unique identifier can be associated with each item. コレクション変更アクションとして 'リセット' を使用する場合にお勧めします。Recommended when using 'Reset' as the collection change action.

      コントロールで、INotifyCollectionChanged または IObservableVector イベントの一部としてハード 'リセット' アクションを受信した後、既存の UI を非常に効率的に回復できるようにします。Enables the control to very efficiently recover the existing UI after receiving a hard 'Reset' action as part of an INotifyCollectionChanged or IObservableVector event. リセットを受信した後、コントロールでは、既に作成されている要素に現在のデータを関連付けるために、指定された一意の ID が使用されます。After receiving a reset the control will use the provided unique ID to associate the current data with elements it had already created. キーをインデックスにマップしない場合、コントロールでは、データの UI の作成を最初からやり直す必要があると見なす必要があります。Without the key to index mapping the control would have to assume it needs to start over from scratch in creating UI for the data.

IKeyIndexMapping 以外の、上記のインターフェイスでは、ItemsRepeater で、ListView や GridView の場合と同じ動作が提供されます。The interfaces listed above, other than IKeyIndexMapping, provide the same behavior in ItemsRepeater as they do in ListView and GridView.

ItemsSource の次のインターフェイスでは、ListView および GridView コントロールで特別な機能が有効になりますが、現在、ItemsRepeater で影響はありません。The following interfaces on an ItemsSource enable special functionality in the ListView and GridView controls, but currently have no effect on an ItemsRepeater:

ヒント

ご意見をお寄せくださいWe want your feedback! Windows UI ライブラリ GitHub プロジェクトでご意見をお知らせください。Let us know what you think on the Windows UI Library GitHub project. 次の #374 などの既存の提案に対する意見の追加をご検討ください:ItemsRepeater の段階的な読み込みのサポートを追加する。Consider adding your thoughts on existing proposals such as #374: Add incremental loading support for ItemsRepeater.

ユーザーが上下にスクロールしたときに、データを段階的に読み込む別の方法は、ScrollViewer のビューポートの位置を監視し、ビューポートがエクステントに近づいたときにさらにデータを読み込むことです。An alternative approach to incrementally load your data as the user scrolls up or down is to observe the position of the ScrollViewer's viewport and load more data as the viewport approaches the extent.

<ScrollViewer ViewChanged="ScrollViewer_ViewChanged">
    <ItemsRepeater ItemsSource="{x:Bind MyItemsSource}" .../>
</ScrollViewer>
private async void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
    if (!e.IsIntermediate)
    {
        var scroller = (ScrollViewer)sender;
        var distanceToEnd = scroller.ExtentHeight - (scroller.VerticalOffset + scroller.ViewportHeight);

        // trigger if within 2 viewports of the end
        if (distanceToEnd <= 2.0 * scroller.ViewportHeight
                && MyItemsSource.HasMore && !itemsSource.Busy)
        {
            // show an indeterminate progress UI
            myLoadingIndicator.Visibility = Visibility.Visible;

            await MyItemsSource.LoadMoreItemsAsync(/*DataFetchSize*/);

            loadingIndicator.Visibility = Visibility.Collapsed;
        }
    }
}

項目のレイアウト変更Change the layout of items

ItemsRepeater によって表示される項目は、その子要素のサイズ設定と配置を管理する Layout オブジェクトによって配置されます。Items shown by the ItemsRepeater are arranged by a Layout object that manages the sizing and positioning of its child elements. ItemsRepeater と共に使用する場合、Layout オブジェクトによって UI の仮想化が有効になります。When used with an ItemsRepeater, the Layout object enables UI virtualization. 指定されているレイアウトは、StackLayoutUniformGridLayout です。The layouts provided are StackLayout and UniformGridLayout. 既定では、ItemsRepeater で垂直方向の StackLayout が使用されます。By default, ItemsRepeater uses a StackLayout with vertical orientation.

StackLayoutStackLayout

StackLayout では 1 行に要素が配置され、これを水平方向または垂直方向に設定することができます。StackLayout arranges elements into a single line that you can orient horizontally or vertically.

Spacing プロパティを設定することで、項目間のスペースの量を調整できます。You can set the Spacing property to adjust the amount of space between items. Spacing は、レイアウトの Orientation の方向に適用されます。Spacing is applied in the direction of the layout's Orientation.

スタック レイアウトの間隔

この例では、ItemsRepeater.Layout プロパティの StackLayout を水平方向に、間隔を 8 ピクセルに設定します。This example shows how to set the ItemsRepeater.Layout property to a StackLayout with horizontal orientation and spacing of 8 pixels.

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<muxc:ItemsRepeater ItemsSource="{x:Bind Items}" ItemTemplate="{StaticResource MyTemplate}">
    <muxc:ItemsRepeater.Layout>
        <muxc:StackLayout Orientation="Horizontal" Spacing="8"/>
    </muxc:ItemsRepeater.Layout>
</muxc:ItemsRepeater>

UniformGridLayoutUniformGridLayout

UniformGridLayout では、折り返しレイアウトで順に要素を配置します。The UniformGridLayout positions elements sequentially in a wrapping layout. OrientationHorizontal の場合、項目は左から右の順にレイアウトされ、Orientation が Vertical の場合は、上から下にレイアウトされます。Items are layed out in order from left-to-right when the Orientation is Horizontal, and layed out top-to-bottom when the Orientation is Vertical. すべての項目のサイズが同じように設定されます。Every item is sized equally.

均一なグリッド レイアウトの間隔

水平レイアウトの各行の項目数は、項目の最小の幅の影響を受けます。The number of items in each row of a horizontal layout is influenced by the minimum item width. 垂直レイアウトの各列の項目数は、項目の最小の高さの影響を受けます。The number of items in each column of a vertical layout is influenced by the minimum item height.

  • 使用する最小サイズは、MinItemHeight および MinItemWidth プロパティを設定することで、明示的に指定できます。You can explicitly provide a minimum size to use by setting the MinItemHeight and MinItemWidth properties.
  • 最小サイズを指定しない場合、最初の項目の測定されたサイズが項目ごとの最小サイズと見なされます。If you don't specify a minimum size, the measured size of the first item is considered the minimum size per item.

また、行と列の間に含めるレイアウトの最小間隔は、MinColumnSpacingMinRowSpacing プロパティを設定することで、設定できます。You can also set minimum spacing for the layout to include between rows and columns by setting the MinColumnSpacing and MinRowSpacing properties.

均一なグリッドのサイズと間隔の設定

行または列内の項目の数が項目の最小サイズと間隔に基づいて決定された後、(前の図で示したとおり) 行または列の最後の項目の後に未使用のスペースが残る可能性があります。After the number if items in a row or column has been determined based on the item's minimum size and spacing, there might be unused space left after the last item in the row or column (as illustrated in the previous image). 余分なスペースについては、無視するか、各項目のサイズを増やすために使用するか、項目間に追加のスペースを作成するために使用するかを指定できます。You can specify whether any extra space is ignored, used to increase the size of each item, or used to create extra space between the items. これは ItemsStretch および ItemsJustification プロパティで制御されます。This is controlled by the ItemsStretch and ItemsJustification properties.

ItemsStretch プロパティを使用すれば、未使用のスペースを埋めるために項目サイズを増やす方法を指定することができます。You can set the ItemsStretch property to specify how the item size is increased to fill the unused space.

このリストには使用可能な値が示されています。This list shows the available values. 定義では、既定の OrientationHorizontal であることが前提となります。The definitions assume the default Orientation of Horizontal.

  • なし:余分なスペースが行の末尾に未使用のまま残されます。None: Extra space is left unused at the end of the row. これが既定値です。This is the default.
  • Fill:使用可能なスペースを使い切るように、項目に追加の幅 (垂直の場合は高さ) が指定されます。Fill: The items are given extra width to use up the available space (height if vertical).
  • Uniform:使用可能なスペースを使い切るように、項目に追加の幅が指定され、縦横比を維持するために追加の高さが指定されます (垂直の場合は、高さと幅が切り替わります)。Uniform: The items are given extra width to use up the available space, and given extra height in order to maintain aspect ratio (height and width are switched if vertical).

この図は、水平レイアウトでの ItemsStretch 値の効果を示しています。This image shows the effect of the ItemsStretch values in a horizontal layout.

均一なグリッド項目のストレッチ

ItemsStretchNone の場合は、ItemsJustification プロパティを設定し、余分なスペースを使用して項目を揃える方法を指定できます。When ItemsStretch is None, you can set the ItemsJustification property to specify how extra space is used to align the items.

このリストには使用可能な値が示されています。This list shows the available values. 定義では、既定の OrientationHorizontal であることが前提となります。The definitions assume the default Orientation of Horizontal.

  • Start:項目は行の先頭に揃えられます。Start: Items are aligned with the start of the row. 余分なスペースが行の末尾に未使用のまま残されます。Extra space is left unused at the end of the row. これが既定値です。This is the default.
  • Center:項目は行の中央に揃えられます。Center: Items are aligned in the center of the row. 余分なスペースは、行の先頭と末尾に均等に分割されます。Extra space is divided evenly at the start and end of the row.
  • End:項目は行の末尾に揃えられます。End: Items are aligned with the end of the row. 余分なスペースが行の先頭に未使用のまま残されます。Extra space is left unused at the start of the row.
  • SpaceAround:項目は均等に分散されます。SpaceAround: Items are distributed evenly. 各項目の前後に同量のスペースが追加されます。An equal amount of space is added before and after each item.
  • SpaceBetween:項目は均等に分散されます。SpaceBetween: Items are distributed evenly. 各項目の間に同量のスペースが追加されます。An equal amount of space is added between each item. 行の先頭と末尾にはスペースは追加されません。No space is added at the start and end of the row.
  • SpaceEvenly:項目は、各項目間および行の先頭と末尾の両方に、等しいスペースで均等に分散されます。SpaceEvenly: Items are distributed evenly with an equal amount of space both between each item and at the start and end of the row.

この図には、垂直レイアウトでの ItemsStretch 値の効果が示されています (行ではなく、列に適用)。This image shows the effect of the ItemsStretch values in a vertical layout (applied to columns instead of rows).

均一なグリッド項目の位置揃え

ヒント

ItemsStretch プロパティは、レイアウトの_測定_ パスに影響します。The ItemsStretch property affects the measure pass of layout. ItemsJustification プロパティは、レイアウトの_配置_ パスに影響します。The ItemsJustification property affects the arrange pass of layout.

この例では、ItemsRepeater.Layout プロパティを UniformGridLayout に設定する方法を示します。This example shows how to set the ItemsRepeater.Layout property to a UniformGridLayout.

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<muxc:ItemsRepeater ItemsSource="{x:Bind Items}"
                    ItemTemplate="{StaticResource MyTemplate}">
    <muxc:ItemsRepeater.Layout>
        <muxc:UniformGridLayout MinItemWidth="200"
                                MinColumnSpacing="28"
                                ItemsJustification="SpaceAround"/>
    </muxc:ItemsRepeater.Layout>
</muxc:ItemsRepeater>

ライフサイクル イベントLifecycle events

ItemsRepeater で項目をホストするときに、コンテンツの非同期ダウンロードの開始、選択を追跡するメカニズムと要素との関連付け、あるいはバックグラウンド タスクの停止など、項目が表示されたとき、または表示が中止されたときに何らかのアクションが必要な場合があります。When you host items in an ItemsRepeater, you might need to take some action when an item is shown or stops being shown, such as start an asynchronous download of some content, associate the element with a mechanism to track selection, or stop some background task.

仮想化コントロールでは、Loaded/Unloaded イベントに依存することはできません。これは、要素がリサイクル時にライブ ビジュアル ツリーから削除されない場合があるためです。In a virtualizing control, you cannot rely on Loaded/Unloaded events because the element might not be removed from the live visual tree when it's recycled. 代わりに、その他のイベントが、要素のライフサイクルを管理するために提供されます。Instead, other events are provided to manage the lifecycle of elements. この図では、ItemsRepeater での要素のライフサイクルと、関連イベントがいつ発生するかが示されています。This diagram shows the lifecycle of an element in an ItemsRepeater, and when the related events are raised.

ライフ サイクル イベントの図

  • ElementPrepared は、要素が使用できる状態になるたびに発生します。ElementPrepared occurs each time an element is made ready for use. これは、新しく作成された要素と、既に存在していてリサイクル キューから再利用されている要素の両方で発生します。This occurs for both a newly created element as well as an element that already exists and is being re-used from the recycle queue.
  • ElementClearing は、認識された項目の範囲から外れた場合など、要素がリサイクル キューに送信されるたびにすぐに発生します。ElementClearing occurs immediately each time an element has been sent to the recycle queue, such as when it falls outside the range of realized items.
  • ElementIndexChanged は、表される項目のインデックスが変更されている、認識済みの各 UIElement で発生します。ElementIndexChanged occurs for each realized UIElement where the index for the item it represents has changed. たとえば、別の項目がデータ ソースで追加または削除された場合、次の順番にある項目のインデックスでこのイベントが受信されます。For example, when another item is added or removed in the data source, the index for items that come after in the ordering receive this event.

この例では、これらのイベントを使用してカスタム選択サービスをアタッチし、項目を表示するために ItemsRepeater を使用するカスタム コントロールで項目の選択を追跡する方法を示します。This example shows how you could use these events to attach a custom selection service to track item selection in a custom control that uses ItemsRepeater to display items.

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<UserControl ...>
    ...
    <ScrollViewer>
        <muxc:ItemsRepeater ItemsSource="{x:Bind Items}"
                            ItemTemplate="{StaticResource MyTemplate}"
                            ElementPrepared="OnElementPrepared"
                            ElementIndexChanged="OnElementIndexChanged"
                            ElementClearing="OnElementClearing">
        </muxc:ItemsRepeater>
    </ScrollViewer>
    ...
</UserControl>
interface ISelectable
{
    int SelectionIndex { get; set; }
    void UnregisterSelectionModel(SelectionModel selectionModel);
    void RegisterSelectionModel(SelectionModel selectionModel);
}

private void OnElementPrepared(ItemsRepeater sender, ElementPreparedEventArgs args)
{
    var selectable = args.Element as ISelectable;
    if (selectable != null)
    {
        // Wire up this item to recognize a 'select' and listen for programmatic
        // changes to the selection model to know when to update its visual state.
        selectable.SelectionIndex = args.Index;
        selectable.RegisterSelectionModel(this.SelectionModel);
    }
}

private void OnElementIndexChanged(ItemsRepeater sender, ElementIndexChangedEventArgs args)
{
    var selectable = args.Element as ISelectable;
    if (selectable != null)
    {
        // Sync the ID we use to notify the selection model when the item
        // we represent has changed location in the data source.
        selectable.SelectionIndex = args.NewIndex;
    }
}

private void OnElementClearing(ItemsRepeater sender, ElementClearingEventArgs args)
{
    var selectable = args.Element as ISelectable;
    if (selectable != null)
    {
        // Disconnect handlers to recognize a 'select' and stop
        // listening for programmatic changes to the selection model.
        selectable.UnregisterSelectionModel(this.SelectionModel);
        selectable.SelectionIndex = -1;
    }
}

データの並べ替え、フィルター処理、リセットSorting, Filtering and Resetting the Data

データ セットのフィルター処理や並べ替えなどのアクションを実行するときに、従来は前のデータ セットと新しいデータを比較してから、INotifyCollectionChanged を使用して詳細な変更通知を発行していたかもしれません。When you perform actions such as filtering or sorting your data set, you traditionally may have compared the previous set of data to the new data, then issued granular change notifications via INotifyCollectionChanged. しかし、多くの場合、古いデータを新しいデータに完全に置き換え、代わりにリセット アクションを使用してコレクション変更通知をトリガーするほうが簡単です。However, it is often easier to completely replace the old data with the new data and trigger a collection change notification using the Reset action instead.

通常、リセットにより、コントロールで既存の子要素が解放され、スクロール位置 0 で最初から UI のビルドをやり直すことになります。これは、リセット時にデータの変更方法が正確に認識されないためです。Typically, a reset causes a control to release existing child elements and start over, building the UI from the beginning at scroll position 0 as it has no awareness of exactly how the data has changed during the reset.

しかし、ItemsSource として割り当てられているコレクションで、IKeyIndexMapping インターフェイスを実装することで一意識別子がサポートされる場合、ItemsRepeater で以下をすばやく識別できます。However, if the collection assigned as the ItemsSource supports unique identifiers by implementing the IKeyIndexMapping interface, then the ItemsRepeater can quickly identify:

  • データの再利用可能な UIElement のうち、リセットの前と後の両方に存在していたものreusable UIElements for data that existed both before and after the reset
  • 以前表示されていた項目のうち、削除されたものpreviously visible items that were removed
  • 新しく追加された項目のうち、表示されるものnew items added that will be visible

これにより、ItemsRepeater でスクロール位置 0 からのやり直しが回避されます。This lets the ItemsRepeater avoid starting over from scroll position 0. また、リセットで変更されなかったデータの UIElement をすばやく復元でき、その結果、パフォーマンスが向上します。It also lets it quickly restore the UIElements for data that didn't change in a reset, resulting in better performance.

この例では、MyItemsSource が項目の基になるリストを折り返すカスタム データ ソースである、垂直スタックで項目のリストを表示する方法を示します。This example shows how to display a list of items in a vertical stack where MyItemsSource is a custom data source that wraps an underlying list of items. Data プロパティが公開され、これを使用して新しいリストを再度割り当て、項目ソースとして使用し、その後、リセットをトリガーすることができます。It exposes a Data property that can be used to re-assign a new list to use as the items source, which then triggers a reset.

<ScrollViewer x:Name="sv">
    <ItemsRepeater x:Name="repeater"
                ItemsSource="{x:Bind MyItemsSource}"
                ItemTemplate="{StaticResource MyTemplate}">
       <ItemsRepeater.Layout>
           <StackLayout ItemSpacing="8"/>
       </ItemsRepeater.Layout>
   </ItemsRepeater>
</ScrollViewer>
public MainPage()
{
    this.InitializeComponent();

    // Similar to an ItemsControl, a developer sets the ItemsRepeater's ItemsSource.
    // Here we provide our custom source that supports unique IDs which enables
    // ItemsRepeater to be smart about handling resets from the data.
    // Unique IDs also make it easy to do things apply sorting/filtering
    // without impacting any state (i.e. selection).
    MyItemsSource myItemsSource = new MyItemsSource(data);

    repeater.ItemsSource = myItemsSource;

    // ...

    // We can sort/filter the data using whatever mechanism makes the
    // most sense (LINQ, database query, etc.) and then reassign
    // it, which in our implementation triggers a reset.
    myItemsSource.Data = someNewData;
}

// ...


public class MyItemsSource : IReadOnlyList<ItemBase>, IKeyIndexMapping, INotifyCollectionChanged
{
    private IList<ItemBase> _data;

    public MyItemsSource(IEnumerable<ItemBase> data)
    {
        if (data == null) throw new ArgumentNullException();

        this._data = data.ToList();
    }

    public IList<ItemBase> Data
    {
        get { return _data; }
        set
        {
            _data = value;

            // Instead of tossing out existing elements and re-creating them,
            // ItemsRepeater will reuse the existing elements and match them up
            // with the data again.
            this.CollectionChanged?.Invoke(
                this,
                new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }

    #region IReadOnlyList<T>

    public ItemBase this[int index] => this.Data != null
        ? this.Data[index]
        : throw new IndexOutOfRangeException();

    public int Count => this.Data != null ? this.Data.Count : 0;
    public IEnumerator<ItemBase> GetEnumerator() => this.Data.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

    #endregion

    #region INotifyCollectionChanged

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    #endregion

    #region IKeyIndexMapping

    private int lastRequestedIndex = IndexNotFound;
    private const int IndexNotFound = -1;

    // When UniqueIDs are supported, the ItemsRepeater caches the unique ID for each item
    // with the matching UIElement that represents the item.  When a reset occurs the
    // ItemsRepeater pairs up the already generated UIElements with items in the data
    // source.
    // ItemsRepeater uses IndexForUniqueId after a reset to probe the data and identify
    // the new index of an item to use as the anchor.  If that item no
    // longer exists in the data source it may try using another cached unique ID until
    // either a match is found or it determines that all the previously visible items
    // no longer exist.
    public int IndexForUniqueId(string uniqueId)
    {
        // We'll try to increase our odds of finding a match sooner by starting from the
        // position that we know was last requested and search forward.
        var start = lastRequestedIndex;
        for (int i = start; i < this.Count; i++)
        {
            if (this[i].PrimaryKey.Equals(uniqueId))
                return i;
        }

        // Then try searching backward.
        start = Math.Min(this.Count - 1, lastRequestedIndex);
        for (int i = start; i >= 0; i--)
        {
            if (this[i].PrimaryKey.Equals(uniqueId))
                return i;
        }

        return IndexNotFound;
    }

    public string UniqueIdForIndex(int index)
    {
        var key = this[index].PrimaryKey;
        lastRequestedIndex = index;
        return key;
    }

    #endregion
}

カスタム コレクション コントロールを作成するCreate a custom collection control

ItemsRepeater を使用すれば、各項目を表示する独自の種類のコントロールを備えたカスタム コレクション コントロールを作成することができます。You can use the ItemsRepeater to create a custom collection control complete with its own type of control to present each item.

注意

これは ItemsControl を使用する場合と似ていますが、ItemsControl から派生させ、コントロール テンプレートに ItemsPresenter を配置するのではなく、Control から派生させ、コントロール テンプレートに ItemsRepeater を挿入します。This is similar to using ItemsControl, but instead of deriving from ItemsControl and putting an ItemsPresenter in the control template, you derive from Control and insert an ItemsRepeater in the control template. ItemsRepeater はカスタム コレクション コントロールに "含まれ" ているのに対して、ItemsControl はカスタム コレクション コントロール "である" ことになります。The custom collection control "has an" ItemsRepeater versus "is an" ItemsControl. これは、サポートしない継承済みのプロパティではなく、公開するプロパティを明示的に選ぶ必要もあることを意味します。This implies that you must also explicitly choose which properties to expose, rather than which inherited properties to not support.

この例では、MediaCollectionView という名前のカスタム コントロールのテンプレートで ItemsRepeater を配置し、そのプロパティを公開する方法を示します。This example shows how to place an ItemsRepeater in the template of a custom control named MediaCollectionView and expose its properties.

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<Style TargetType="local:MediaCollectionView">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MediaCollectionView">
                <Border
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
                    <ScrollViewer x:Name="ScrollViewer">
                        <muxc:ItemsRepeater x:Name="ItemsRepeater"
                                            ItemsSource="{TemplateBinding ItemsSource}"
                                            ItemTemplate="{TemplateBinding ItemTemplate}"
                                            Layout="{TemplateBinding Layout}"
                                            TabFocusNavigation="{TemplateBinding TabFocusNavigation}"/>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
public sealed class MediaCollectionView : Control
{
    public object ItemsSource
    {
        get { return (object)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ItemsSource.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(MediaCollectionView), new PropertyMetadata(0));

    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ItemTemplate.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ItemTemplateProperty =
        DependencyProperty.Register(nameof(ItemTemplate), typeof(DataTemplate), typeof(MediaCollectionView), new PropertyMetadata(0));

    public Layout Layout
    {
        get { return (Layout)GetValue(LayoutProperty); }
        set { SetValue(LayoutProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Layout.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty LayoutProperty =
        DependencyProperty.Register(nameof(Layout), typeof(Layout), typeof(MediaCollectionView), new PropertyMetadata(0));

    public MediaCollectionView()
    {
        this.DefaultStyleKey = typeof(MediaCollectionView);
    }
}

グループ化された項目を表示するDisplay grouped items

別の ItemsRepeater の ItemTemplateItemsRepeater を入れ子にすることで、入れ子になった仮想化レイアウトを作成できます。You can nest an ItemsRepeater in the ItemTemplate of another ItemsRepeater to create nested virtualizing layouts. フレームワークでは、表示されていないか、現在のビューポートの近くにない要素の不要な認識を最小限に抑えることで、リソースが効率的に利用されます。The framework will make efficient use of resources by minimizing unnecessary realization of elements that aren't visible or near the current viewport.

この例では、垂直スタックでグループ化された項目のリストを表示する方法を示します。This example shows how you can display a list of grouped items in a vertical stack. 外部の ItemsRepeater で各グループが生成されます。The outer ItemsRepeater generates each group. 各グループのテンプレートでは、別の ItemsRepeater で項目が生成されます。In the template for each group, another ItemsRepeater generates the items.

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<ScrollViewer>
  <muxc:ItemsRepeater ItemsSource="{x:Bind AppNotifications}"
                      Layout="{StaticResource MyGroupLayout}">
    <muxc:ItemsRepeater.ItemTemplate>
      <DataTemplate x:DataType="ExampleApp:AppNotifications">
        <!-- Group -->
        <StackPanel>
          <!-- Header -->
          TextBlock Text="{x:Bind AppTitle}"/>
          <!-- Items -->
          <muxc:ItemsRepeater ItemsSource="{x:Bind Notifications}"
                              Layout="{StaticResource MyItemLayout}"
                              ItemTemplate="{StaticResource MyTemplate}"/>
          <!-- Footer -->
          <Button Content="{x:Bind FooterText}"/>
        </StackPanel>
      </DataTemplate>
    </muxc:ItemsRepeater.ItemTemplate>
  </muxc:ItemsRepeater>
</ScrollViewer>

この例では、以下に示すように、ユーザー設定で変更でき、水平スクロール リストとして表示される、さまざまなカテゴリがあるアプリのレイアウトを示します。This example shows a layout for an app that has various categories that can change with user preference and are presented as horizontally scrolling lists, as shown here.

items repeater を使用して入れ子にされたレイアウト

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<!-- Include the <muxc:ItemsRepeaterScrollHost> if targeting Windows 10 versions earlier than 1809. -->
<ScrollViewer>
  <muxc:ItemsRepeater ItemsSource="{x:Bind Categories}"
                      Background="LightGreen">
    <muxc:ItemsRepeater.ItemTemplate>
      <DataTemplate x:DataType="local:Category">
        <StackPanel Margin="12,0">
          <TextBlock Text="{x:Bind Name}" Style="{ThemeResource TitleTextBlockStyle}"/>
          <!-- Include the <muxc:ItemsRepeaterScrollHost> if targeting Windows 10 versions earlier than 1809. -->
          <ScrollViewer HorizontalScrollMode="Enabled"
                                          VerticalScrollMode="Disabled"
                                          HorizontalScrollBarVisibility="Auto" >
            <muxc:ItemsRepeater ItemsSource="{x:Bind Items}"
                                Background="Orange">
              <muxc:ItemsRepeater.ItemTemplate>
                <DataTemplate x:DataType="local:CategoryItem">
                  <Grid Margin="10"
                        Height="60" Width="120"
                        Background="LightBlue">
                    <TextBlock Text="{x:Bind Name}"
                               Style="{StaticResource SubtitleTextBlockStyle}"
                               Margin="4"/>
                  </Grid>
                </DataTemplate>
              </muxc:ItemsRepeater.ItemTemplate>
              <muxc:ItemsRepeater.Layout>
                <muxc:StackLayout Orientation="Horizontal"/>
              </muxc:ItemsRepeater.Layout>
            </muxc:ItemsRepeater>
          </ScrollViewer>
        </StackPanel>
      </DataTemplate>
    </muxc:ItemsRepeater.ItemTemplate>
  </muxc:ItemsRepeater>
</ScrollViewer>

要素をビューで表示するBringing an Element Into View

XAML フレームワークでは既に、1) キーボードのフォーカスを受け取ったとき、または 2) ナレーターのフォーカスを受け取ったときにビューでの FrameworkElement の表示が処理されています。The XAML framework already handles bringing a FrameworkElement into view when it either 1) receives keyboard focus or 2) receives Narrator focus. 要素を明示的にビューで表示する必要があるケースが他にもある場合があります。There may be other cases where you need to explicitly bring an element into view. たとえば、ユーザー アクションに応答する場合や、ページ ナビゲーション後に UI の状態を復元する場合です。For example, in response to a user action or to restore the state of the UI after a page navigation.

仮想化された要素をビューで表示するには、以下の操作が必要です。Bringing a virtualized element into view involves the following:

  1. 項目の UIElement を認識するRealize a UIElement for an item
  2. レイアウトを実行し、確実に要素に有効な位置が指定されるようにするRun the layout to ensure the element has a valid position
  3. 認識された要素を表示する要求を開始するInitiate a request to bring the realized element into view

以下の例では、ページ ナビゲーション後のフラットな垂直リストでの項目のスクロール位置の復元の一環として、これらの手順を示します。The example below demonstrates these steps as part of restoring the scroll position of an item in a flat, vertical list after a page navigation. 入れ子になった ItemsRepeater を使用する階層データの場合、方法は同じですが、階層レベルごとに実行する必要があります。In the case of hierarchical data using nested ItemsRepeaters the approach is essentially the same, but must be done at each level of the hierarchy.

<ScrollViewer x:Name="scrollviewer">
  <ItemsRepeater x:Name="repeater" .../>
</ScrollViewer>
public class MyPage : Page
{
    // ...

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

            // retrieve saved offset + index(es) of the tracked element and then bring it into view.
            // ... 

            var element = repeater.GetOrCreateElement(index);

            // ensure the item is given a valid position
            element.UpdateLayout();

            element.StartBringIntoView(new BringIntoViewOptions()
            {
                VerticalOffset = relativeVerticalOffset
            });
    }

    protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
    {
        base.OnNavigatingFrom(e);

        // retrieve and save the relative offset and index(es) of the scrollviewer's current anchor element ...
        var anchor = this.scrollviewer.CurrentAnchor;
        var index = this.repeater.GetElementIndex(anchor);
        var anchorBounds = anchor.TransformToVisual(this.scrollviewer).TransformBounds(new Rect(0, 0, anchor.ActualWidth, anchor.ActualHeight));
        relativeVerticalOffset = this.sv.VerticalOffset – anchorBounds.Top;
    }
}

アクセシビリティを有効にするEnable Accessibility

ItemsRepeater では、既定のアクセシビリティ エクスペリエンスは提供されません。ItemsRepeater does not provide a default accessibility experience. UWP アプリのユーザビリティに関するドキュメントに、確実にアプリで包括的なユーザー エクスペリエンスを提供するのに役立つ豊富な情報が示されています。The documentation on Usability for UWP apps provides a wealth of information to help you ensure your app provides an inclusive user experience. ItemsRepeater を使ってカスタム コントロールを作成する場合は、必ず、カスタム オートメーション ピアに関するドキュメントを参照してください。If you're using the ItemsRepeater to create a custom control then be sure to see the documentation on Custom automation peers.

キーボード操作Keyboarding

ItemsRepeater で提供されるフォーカス移動のためのキーボード操作の最小限のサポートは、XAML のキーボード操作の 2D 方向ナビゲーションに関する記述に基づいています。The minimal keyboarding support for focus movement that ItemsRepeater provides is based on XAML's 2D Directional Navigation for Keyboarding.

方向ナビゲーション

ItemsRepeater の XYFocusKeyboardNavigation モードは、既定で Enabled になっています。The ItemsRepeater's XYFocusKeyboardNavigation mode is Enabled by default. 目的のエクスペリエンスに応じて、Home、End、PageUp、PageDown などの一般的なキーボード操作のサポートの追加を検討してください。Depending on the intended experience, consider adding support for common Keyboard Interactions such as Home, End, PageUp, and PageDown.

ItemsRepeater では、項目の既定のタブ順序が (仮想化されているかどうかに関わらず)、データ内に項目が指定されているのと同じ順序に従っていることが自動的に確保されます。The ItemsRepeater does automatically ensure that the default tab order for its items (whether virtualized or not) follows the same order that the items are given in the data. ItemsRepeater では、既定でその TabFocusNavigation プロパティが、一般的な既定値である Local ではなく、Once に設定されます。By default the ItemsRepeater has its TabFocusNavigation property set to Once instead of the common default of Local.

注意

ItemsRepeater では、最後にフォーカスが置かれた項目が自動的に記憶されません。The ItemsRepeater does not automatically remember the last focused item. これは、ユーザーが Shift + Tab キーを使用したときに、最後に認識された項目に移動される可能性があることを意味します。This means that when a user is using Shift+Tab they may be taken to the last realized item.

スクリーン リーダーでの "YX 項目" の読み上げAnnouncing "Item X of Y" in Screen Readers

PositionInSetSizeOfSet の値などの、適切なオートメーション プロパティの設定を管理する必要があり、項目の追加、移動、削除などが行われた場合、確実に最新の状態が保たれているようにする必要があります。You need to manage setting the appropriate automation properties, such as values for PositionInSet and SizeOfSet, and ensure they remain up-to-date when items are added, moved, removed, etc.

一部のカスタム レイアウトでは、表示順序が明白でない場合があります。In some custom layouts there may not be an obvious sequence to the visual order. ユーザーは最低でも、スクリーン リーダーによって使用される PositionInSet および SizeOfSet プロパティの値が、データでの項目の表示順序と一致することを期待します (0 ベースではなく、自然計数と一致させるために 1 単位のオフセット)。Users minimally expect that the values for the PositionInSet and SizeOfSet properties used by screen readers will match the order the items appear in the data (offset by 1 to match natural counting versus being 0-based).

これを実現する最善の方法は、項目コントロールのオートメーション ピアで GetPositionInSetCore および GetSizeOfSetCore メソッドを実装し、コントロールによって表されるデータ セットの項目の位置をレポートすることです。The best way to achieve this is by having the automation peer for the item control implement the GetPositionInSetCore and GetSizeOfSetCore methods and report the position of the item in the data set represented by the control. 支援技術によるアクセスの実行時にのみ、値が計算され、それを最新の状態に保つことが大変なことではなくなります。The value is only computed at run-time when accessed by an assistive technology and keeping it up-to-date becomes a non-issue. 値はデータの順序と一致します。The value matches the data order.

この例では、CardControl と呼ばれるカスタム コントロールを表示するときに、これをどのように実行するかを示します。This example shows how you could do this when presenting a custom control called CardControl.

<ScrollViewer >
    <ItemsRepeater x:Name="repeater" ItemsSource="{x:Bind MyItemsSource}">
       <ItemsRepeater.ItemTemplate>
           <DataTemplate x:DataType="local:CardViewModel">
               <local:CardControl Item="{x:Bind}"/>
           </DataTemplate>
       </ItemsRepeater.ItemTemplate>
   </ItemsRepeater>
</ScrollViewer>
internal sealed class CardControl : CardControlBase
{
    protected override AutomationPeer OnCreateAutomationPeer() => new CardControlAutomationPeer(this);

    private sealed class CardControlAutomationPeer : FrameworkElementAutomationPeer
    {
        private readonly CardControl owner;

        public CardControlAutomationPeer(CardControl owner) : base(owner) => this.owner = owner;

        protected override int GetPositionInSetCore()
          => ((ItemsRepeater)owner.Parent)?.GetElementIndex(this.owner) + 1 ?? base.GetPositionInSetCore();

        protected override int GetSizeOfSetCore()
          => ((ItemsRepeater)owner.Parent)?.ItemsSourceView?.Count ?? base.GetSizeOfSetCore();
    }
}