スクロール ビューアー コントロール

1 つの領域には収まらない UI コンテンツがある場合は、スクロール ビューアー コントロールを使用します。

スクロール ビューアーにより、ビューポート (表示可能な領域) の境界外のコンテンツを拡張表示できるようになります。 ユーザーはこのコンテンツを表示するために、タッチ、マウス ホイール、キーボード、ゲームパッドでスクロール ビューアーのサーフェスを操作します。またはマウスやペン カーソルでスクロール ビューアーのスクロールバーを操作します。

状況によって、スクロール ビューアーのスクロールバーは 2 つの視覚化を使用します (以下の画像参照)。左がパン インジケーター、右が従来のスクロールバーのつまみです。

A screenshot that illustrates a panning scrollbar, a 2 pixel wide vertical line at the right edge of the content.

A screenshot that illustrates the standard scrollbar, a 6 pixel wide vertical line with an up arrow button at the top, and a down arrow at the bottom.

重要

WinUI 3 には、ScrollViewerScrollView という 2 つのスクロール ビューアー コントロールがあります。 スクロール ビューアー コントロールについての全般的な説明は、両方のコントロールに当てはまる情報です。

スクロール、パン、ズーム

スクロール ビューアー コントロールを使用して、コンテンツのスクロールパンズームを許可します。

  • スクロール: スクロール バーのつまみをドラッグするか、マウスのスクロール ホイールを使用して、コンテンツを垂直方向または水平方向に移動します。
  • パン: タッチ入力またはペン入力を使用してコンテンツを垂直方向または水平方向に移動します。
  • ズーム: コンテンツのスケールを拡大または縮小します。

スクロールバーはユーザーの入力方式を理解して、どの視覚化を表示すればよいか判断します。

  • たとえば、スクロールバーが直接操作されずに領域がスクロールされると、パン インジケーターが表示されて現在のスクロール位置が示されます。
  • マウスかペン カーソルがパン インジケーターの上に移動すると、パン インジケーターが従来のスクロール バーに変形します。 スクロールバーのつまみをドラッグすると、スクロール領域が操作されます。

An animation that shows the scroll bar transform from the narrow panning indicator to the traditional thumb when the cursor moves over it.

Note

スクロールバーは、表示されると ScrollViewer 内のコンテンツの上部に 16 ピクセルでオーバーレイされます。 UX を適切に設計するには、このオーバーレイによってインタラクティブなコンテンツが隠れないようにする必要があります。 また、UX を重複させないようにするには、スクロールバーを考慮してビューポートの端のパディングを 16 ピクセル残すようにしてください。

ビューポートと範囲

スクロール ビューアーは 2 つのメイン領域から成っており、これらの領域はその機能を理解するために重要です。 エクステントは、非表示および表示のいずれの場合にもスクロール可能なすべてのコンテンツを含む領域です。 ビューポートは、コンテンツが表示されるコントロールの表示領域です。

A block of text that extends beyond the viewport, or visible area of the control.

これらの領域の高さと幅、スクロール可能な高さと幅 (エクステント サイズとビューポート サイズの違い) を取得できるさまざまな API が用意されています。

推奨事項

  • できる限り、水平方向ではなく垂直方向のスクロールを設計してください。
  • コンテンツ領域が 1 つのビューポート境界 (垂直方向または水平方向) を超えている場合は、単一軸のパンを使います。 コンテンツ領域が両方のビューポート境界 (垂直方向と水平方向) を超えている場合は、2 軸のパンを使います。
  • アイテム ビュー、リスト ビュー、グリッド ビュー、コンボ ボックス、リスト ボックス、テキスト入力ボックス、およびハブ コントロールの組み込みのスクロール機能を使います。 こうしたコントロールでは、同時に表示する項目が多すぎる場合に、ユーザーが項目のリストを水平方向、垂直方向のいずれかにスクロールできます。
  • ユーザーがより大きな領域の周囲で両方向にパンすること、そしておそらくズームできるようにする場合、たとえばユーザーが (画面に適合するサイズに設定されたイメージではなく) フル サイズのイメージをパンおよびズームできるようにする場合には、スクロール ビューアー内にイメージを配置します。
  • ユーザーが長いテキスト パスをスクロールする場合、垂直方向にのみスクロールするようにスクロール ビューアーを構成します。
  • 1 つのオブジェクトのみを含める場合にスクロール ビューアーを使います。 1 つのオブジェクトをレイアウト パネルとし、その任意の数のオブジェクトを含めることができる点に注意してください。
  • スクロール可能なビュー (ScrollViewer や ListView など) で UIElement のポインター イベントを処理する必要がある場合は、UIElement.CancelDirectManipulation を呼び出すことにより、ビュー内のこの要素に対する操作イベントのサポートを明示的に無効にする必要があります。 ビューで操作イベントを再び有効にするには、UIElement.TryStartDirectManipulation を呼び出します。

UWP と WinUI 2

Note

ScrollView コントロールは WinUI 3 でのみ使用できます。 UWP と WinUI 2 には ScrollViewer コントロールを使用してください。

重要

この記事の情報と例は、Windows アプリ SDKWinUI 3 を使用するアプリ向けに最適化されていますが、一般に WinUI 2 を使用する UWP アプリに適用されます。 プラットフォーム固有の情報と例については、UWP API リファレンスを参照してください。

このセクションには、UWP または WinUI 2 アプリでコントロールを使用するために必要な情報が含まれています。

このコントロールの API は Windows.UI.Xaml.Controls 名前空間に存在します。

最新の WinUI 2 を使用して、すべてのコントロールの最新のスタイルとテンプレートを取得することをお勧めします。 WinUI 2.2 以降には、丸めた角を使用するこのコントロールの新しいテンプレートが含まれます。 詳しくは、「角の半径」をご覧ください。

スクロール ビューアーを作成する

WinUI 3 ギャラリー アプリには、ほとんどの WinUI 3 コントロールと機能の対話型の例が含まれています。 Microsoft Store からアプリを入手するか、GitHub でソース コードを取得します。

スクロール ビューアー コントロールを使用すると、スクロール ビューアーでコンテンツを明示的にラップするか、コンテンツ コントロールのコントロール テンプレートにスクロール ビューアーを配置して、コンテンツをスクロール可能にすることができます。

コントロール テンプレートにおける ScrollViewer

スクロール ビューアー コントロールが他のコントロールの複合パートとして存在するのは一般的です。 スクロール ビューアー パーツのビューポートは、ホスト コントロールのレイアウト領域が展開されたコンテンツ サイズよりも小さい場合にのみ、スクロール バーと共に表示されます。

ItemsView のテンプレートには ScrollView コントロールが含まれています。 ItemsView.ScrollView プロパティを使用して、ScrollView にアクセスできます。

ListViewGridView テンプレートには、必ず ScrollViewer が含まれています。 TextBoxRichEditBox のテンプレートには ScrollViewer も含まれています。 ScrollViewer で、スタイルで設定してテンプレート バインドで使用できる XAML 添付プロパティの数を定義して、組み込みの ScrollViewer パーツの動作とプロパティの一部に影響を与えます。 添付プロパティについて詳しくは、「添付プロパティの概要」をご覧ください。

スクロール可能なコンテンツを設定する

スクロール ビューアー内のコンテンツは、スクロール ビューアーのビューポートよりも大きい場合にスクロール可能になります

次の使用例では、RectangleScrollView コントロールのコンテンツとして設定しています。 ユーザーには、その四角形の 500 x 400 部分のみが表示され、スクロールして残りの部分を表示できます。

<ScrollView Width="500" Height="400">
    <Rectangle Width="1000" Height="800">
        <Rectangle.Fill>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                <GradientStop Color="Yellow" Offset="0.0" />
                <GradientStop Color="Red" Offset="0.25" />
                <GradientStop Color="Blue" Offset="0.75" />
                <GradientStop Color="LimeGreen" Offset="1.0" />
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
</ScrollView>

Layout

前の例では、四角形のサイズがスクロール ビューアーよりも大きいことを明示的に設定しています。 リストやテキスト ブロックのように、スクロール ビューアーのコンテンツを自然に拡大できる場合は、スクロール ビューアーを構成して、コンテンツ (範囲) を垂直方向、水平方向、両方、または両方に展開できるようにすることができます。

たとえば、このテキスト ブロックは、親コンテナーで制約されるまで水平方向に拡大し、テキストを折り返して垂直方向に拡大します。

<TextBlock Text="{x:Bind someText}" TextWrapping="WrapWholeWords"/>

テキスト ブロックがスクロール ビューアーにラップすると、スクロール ビューアーは水平方向と垂直方向の拡大を制限します。

垂直では、コンテンツが水平方向に制限されますが、ビューポートの境界を超えて垂直方向に拡大でき、ユーザーはコンテンツを上下にスクロールできます。

A block of text that extends vertically beyond the viewport, or visible area of the control, with a vertical scroll bar shown.

水平 では、コンテンツは垂直方向に制約されますが、ビューポートの境界を超えて水平方向に拡大でき、ユーザーはコンテンツを左右にスクロールできます。

A block of text that extends horizontally beyond the viewport, or visible area of the control, with a horizontal scroll bar shown.

スクロールバーの表示

ScrollViewer コントロールと ScrollView コントロールでは、コンテンツの水平方向と垂直方向のスクロールを構成するために、少し異なる方法を使用します。

  • ScrollViewer コントロールでは、VerticalScrollBarVisibility プロパティと HorizontalScrollBarVisibility プロパティによって、スクロール バーの可視性と、特定の方向へのスクロールが許可されるかどうかの両方が制御されます。 プロパティが Disabled に設定されている場合、ユーザーの操作によってコンテンツをその方向にスクロールすることはできません。
    • 既定の設定は VerticalScrollBarVisibility="Auto"HorizontalScrollBarVisibility="Disabled" です。
  • ScrollView コントロールの VerticalScrollBarVisibility プロパティと HorizontalScrollBarVisibility プロパティは、スクロール バーの可視性のみを制御します。
    • 既定の設定は VerticalScrollBarVisibility="Auto"HorizontalScrollBarVisibility="Auto" です。

次の表では、これらのプロパティの表示オプションについて説明します。

説明
Auto スクロール バーは、ビューポートですべてのコンテンツを表示できない場合にのみ表示されます。
無効 (ScrollViewer のみ) スクロール バーは、ビューポートですべてのコンテンツを表示できない場合でも表示されません。 ユーザー操作によるスクロールは無効になっています。 (プログラムによるスクロールは引き続き可能です)。
非表示 スクロール バーは、ビューポートですべてのコンテンツを表示できない場合でも表示されません。 スクロールは引き続き有効であり、タッチ、キーボード、またはマウス ホイールの操作によって行えます。
Visible スクロール バーは常に表示されます。 (現在の UX デザインでは、ビューポートですべてのコンテンツを表示できない場合を除き、スクロール バーはマウス カーソルが上にある場合にのみ表示されます)。

(ScrollViewer は ScrollBarVisibility 列挙型を使用し、ScrollView は ScrollingScrollBarVisibility 列挙型を使用します)。

向き

ScrollView コントロールには ContentOrientation プロパティがあり、コンテンツのレイアウトを制御できます。 このプロパティは、明示的に制限されていないコンテンツを拡大する方法を決定します。 HeightWidth がコンテンツに明示的に設定されている場合、ContentOrientation に効果はありません。

次の表は、ScrollViewContentOrientation オプションと、ScrollViewer の同等の設定を示しています。

向き ScrollView ScrollViewer
垂直 ContentOrientation="Vertical" VerticalScrollBarVisibility="[Auto][Visible][Hidden]"
HorizontalScrollBarVisibility="Disabled"
水平 ContentOrientation="Horizontal" VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="[Auto][Visible][Hidden]"
両方 ContentOrientation="Both" VerticalScrollBarVisibility="[Auto][Visible][Hidden]"
HorizontalScrollBarVisibility="[Auto][Visible][Hidden]"
なし ContentOrientation="None"
VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Disabled"

垂直レイアウト

既定では、スクロール ビューアーのコンテンツ レイアウト (向き) は垂直方向です。

この例では、ItemsRepeater が ScrollView の Content として使用されます。 ItemsRepeater の UniformGridLayout は、スペースが足りなくなるまでアイテムを水平方向に配置し (この例では 500px)、次の行に次のアイテムを配置します。 ItemsRepeater は、ユーザーが表示できる 400px よりも高い場合がありますが、ユーザーはコンテンツを垂直方向にスクロールできます。

既定の ContentOrientation 値は Vertical であるため、ScrollView を変更する必要はありません。

<ScrollView Width="500" Height="400">
    <ItemsRepeater ItemsSource="{x:Bind Albums}"
                   ItemTemplate="{StaticResource MyTemplate}">
        <ItemsRepeater.Layout>
            <UniformGridLayout RowSpacing="8" ColumnSpacing="8"/>
        </ItemsRepeater.Layout>
    </ItemsRepeater>
</ScrollView>

水平レイアウト

この例では、コンテンツはアイテムを水平方向にレイアウトする StackPanel です。 水平スクロールをサポートし、垂直スクロールを無効にするように、スクロール ビューアーの構成が変更されました。

ScrollViewContentOrientation プロパティをに Horizontal に設定し、コンテンツを必要なだけ水平方向に拡大できるようにします。

<ScrollView Width="500" Height="400" ContentOrientation="Horizontal">
    <StackPanel Orientation="Horizontal">
        <Button Width="200" Content="Button 1"/>
        <Button Width="200" Content="Button 2"/>
        <Button Width="200" Content="Button 3"/>
        <Button Width="200" Content="Button 4"/>
        <Button Width="200" Content="Button 5"/>
    </StackPanel>
</ScrollView>

プログラムによるスクロール

スクロール ビューアーのオフセット プロパティは読み取り専用ですが、プログラムによるスクロールが行えるようにメソッドが用意されています。

ScrollView コントロールのでは、ScrollTo メソッドを呼び出し、スクロールする水平方向と垂直方向のオフセットを渡します。 この場合、スクロールは垂直のみであるため、現在の HorizontalOffset 値が使用されます。 一番上までスクロールするために、0 の VerticalOffset を使用します。 一番下までスクロールする場合、VerticalOffsetScrollableHeight と同じです。

<Button Content="Scroll to top" Click="ScrollTopButton_Click"/>
<Button Content="Scroll to bottom" Click="ScrollBottomButton_Click"/>
<ScrollView x:Name="scrollView" Width="500" Height="400">
    <StackPanel>
        <Button Width="200" Content="Button 1"/>
        <Button Width="200" Content="Button 2"/>
        <Button Width="200" Content="Button 3"/>
        <Button Width="200" Content="Button 4"/>
        <Button Width="200" Content="Button 5"/>
    </StackPanel>
</ScrollView>
private void ScrollTopButton_Click(object sender, RoutedEventArgs e)
{
    scrollView.ScrollTo(
        horizontalOffset: scrollView.HorizontalOffset,
        verticalOffset: 0);
}

private void ScrollBottomButton_Click(object sender, RoutedEventArgs e)
{
    scrollView.ScrollTo(
        horizontalOffset: scrollView.HorizontalOffset,
        verticalOffset: scrollView.ScrollableHeight);
}

ScrollView には、ScrollBy メソッドも用意されており、現在のオフセットから指定した差分だけ垂直方向または水平方向にスクロールできます。

ズーム

ユーザーはスクロール ビューアーを使用すると、コンテンツを光学式に拡大または縮小できます。 光学式ズーム操作は、ピンチジェスチャとストレッチ ジェスチャを介して実行されます (指を遠くに移動するとズームインし、一緒に近づくとズームアウトされます)、または Ctrl キーを押しながらマウスのスクロール ホイールをスクロールします。 ズームの詳細については、「光学式ズームとサイズ変更」を参照してください。

ユーザー操作によるズームを有効にするには、ZoomMode プロパティを Enabled に設定します (既定では Disabled )。 ZoomMode プロパティに対する変更はすぐに有効になり、進行中のユーザー操作に影響する可能性があります。

この例では、ズームを許可するように構成されたスクロール ビューアーにラップされたイメージを示しています。

<ScrollView Width="500" Height="400"
            ContentOrientation="Both"
            ZoomMode="Enabled">
    <Image Source="Assets/rainier.jpg"/>
</ScrollView>

この場合、イメージはスクロール ビューアーによって制約されないため、最初はネイティブ サイズで表示されます。 イメージ ソースがビューポートよりも大きい場合、ユーザーは画像全体を表示するために縮小する必要がありますが、このような操作は意図していない可能性があります。

A picture of a mountain zoomed in so far that only blue sky and clouds in the upper left of the picture are visible.

次の例では、最初に読み込まれたズーム アウトが行われ、必要に応じてユーザーが拡大およびスクロールできるよう、ビューポートにイメージを制限するようにスクロール ビューアーを構成する方法を示します。

A picture of a mountain zoomed out so that the foreground, mountain, and sky are all visible.

イメージを ScrollView のビューポートに制限するには、ContentOrientation プロパティを None に設定します。 スクロール バーの表示設定はこの制約に関連付けられていないため、ユーザーが拡大するとスクロール バーが自動的に表示されます。

<ScrollView Width="500" Height="400"
            ContentOrientation="None"
            ZoomMode="Enabled">
    <Image Source="Assets/rainier.jpg"/>
</ScrollView>

拡大率

ユーザーがコンテンツをズームできる量を制御するには、MinZoomFactor プロパティと MaxZoomFactor プロパティを使用します。 これらのプロパティは、ユーザー操作とプログラムによるズームの両方に有効です。

  • 既定の設定は MinZoomFactor="0.1"MaxZoomFactor="10.0" です。
<ScrollView Width="500" Height="400"
            ContentOrientation="Both"
            ZoomMode="Enabled" 
            MinZoomFactor="1.0" MaxZoomFactor="8.0">
    <Image Source="Assets/rainier.png"/>
</ScrollView>

プログラムによるズーム

ZoomFactor プロパティは読み取り専用ですが、プログラムでズームできるようにメソッドが用意されています。 この一般的な用途は、スクロール ビューアーを、ズームの量を制御するスライダーに接続するか、ズーム レベルをリセットするボタンに接続するというものです。 (ズーム スライダーの例については、WinUI 3 ギャラリー アプリの ScrollViewer を参照してください)。

ScrollView コントロールの場合は、ZoomTo メソッドを呼び出し、最初のパラメーターとして新しいズーム係数を渡します。

<Slider Header="Zoom" IsEnabled="True"
        Maximum="{x:Bind scrollControl.MaxZoomFactor, Mode=OneWay}"
        Minimum="{x:Bind scrollControl.MinZoomFactor, Mode=OneWay}"
        StepFrequency="0.1"
        ValueChanged="ZoomSlider_ValueChanged" />
<ScrollView Width="500" Height="400"
            ContentOrientation="None"
            ZoomMode="Enabled">
    <Image Source="Assets/rainier.png"/>
</ScrollView>
private void ZoomSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
    if (scrollControl != null)
    {
        scrollControl.ZoomTo(
            zoomFactor: (float)e.NewValue,
            centerPoint: null)
    }
}

ScrollView には、現在のズーム レベルから指定した差分でズームインおよびズームアウトできる ZoomBy メソッドも用意されています。

サンプル コードの入手