卷軸視圖控制項

如果您要顯示的 UI 內容多到超過區域所能容納的範圍,請使用捲動檢視器控制項。

捲動檢視器可讓內容延伸到檢視區 (可見區域) 的界限外。 使用者可透過觸控、滑鼠滾輪、鍵盤或遊戲手把操作捲動檢視器的介面,或透過滑鼠或筆游標與捲動檢視器的滾動條進行互動,來存取這些內容。

依情況而定,滾動檢視器的捲動條使用兩種不同的視覺效果,如下圖所示:平移指示器 (左) 和傳統捲動條滑塊 (右)。

螢幕快照,示範一個移動的滾動條,在內容的右邊緣有一條 2 像素寬的垂直線。

此螢幕快照說明標準滾動條、上方有向上箭號按鈕的 6 像素寬垂直線,以及底部的向下箭號。

這很重要

WinUI 3 有兩種捲動檢視器控制項:ScrollViewer 和 ScrollView。 一般在說到捲動檢視器控制項時,同時指涉這兩種控制項。

控制 ScrollView 項的行為和使用方式與控制項類似 ScrollViewer ,但以 InteractionTracker 為基礎,具有動畫驅動檢視變更等新功能,而且其設計目的是確保 ItemsRepeater 的完整功能。

捲動、平移和縮放

使用捲動檢視器控制項,您可以捲動、移動瀏覽和縮放內容。

  • 捲動:藉由拖曳捲動條滑塊或使用滑鼠滾輪來垂直或水平移動內容。
  • 平移:使用觸控或手寫筆輸入,使內容垂直或水平平移。
  • 縮放:從光學上增加或縮小內容的縮放尺寸。

捲軸會感知使用者的輸入方式,並用它來判斷要顯示哪一個視覺效果。

  • 例如,當不直接操縱捲軸而是透過觸控進行捲動時,捲動指示器會出現,顯示目前的捲動位置。
  • 當滑鼠或手寫筆游標移至移動瀏覽指示器上方時,它會變換成傳統捲軸。 拖曳捲軸滑塊可操控捲動區域。

顯示滾動條在游標移動到其上方時,從窄指示器轉換為傳統滑塊的動畫。

備註

當捲軸可見時,它會以 16px 的重疊形式顯示在 ScrollViewer 內的內容上。 為了確保良好 UX 設計,您應該確定此重疊不會遮蔽任何互動式內容。 此外,如果您不希望有 UX 重疊,請在檢視區邊緣保留 16px 的邊框間距,來為捲軸讓出空間。

視窗與範圍

捲動檢視器包含的兩個主要區域,對於瞭解其功能很重要。 包含所有隱藏和可見的可捲動內容區域,是延伸區。 顯示內容的控制項可見區域,是檢視區。

超出檢視區或控件可見區域的文字區塊。

您可以使用各種 API 來取得這些區域的高度和寬度,以及 可捲動的高度和寬度,這也是延伸區大小和檢視區大小的差別。

Recommendations

  • 請盡可能設計為垂直捲動,而不是水平捲動。
  • 對於超出一個檢視區界限 (垂直或水平) 的內容區域,使用單軸平移。 對於超出兩個檢視區界限 (垂直和水平) 的內容區域,使用雙軸平移。
  • 請在項目檢視、清單檢視、網格檢視、下拉式方塊、清單方塊、文字輸入方塊和中樞控制項使用內建捲動功能。 使用這些控制項時,如果一次顯示太多項目,使用者就能夠水平或垂直捲動清單中的項目。
  • 如果您想要讓使用者在更大的區域朝兩種方向移動瀏覽,且也能縮放,舉例來說,如果您想要讓使用者移動瀏覽和縮放全尺寸影像 (而不是讓影像調整為螢幕大小),請將影像放在捲動檢視器內。
  • 如果使用者需要捲動檢視長段落的文字,請將捲動檢視器設為僅限垂直捲動。
  • 在捲動檢視器中容納一個物件即可。 請注意,一個物件可以是布局面板,而它可以包含自身的多個物件。
  • 如果您需要在可捲動的檢視中處理 UIElement 的指標事件 (例如 ScrollViewer 或 ListView),則必須藉由呼叫 UIElement.CancelDirectManipulation,明確對此檢視的元素停用操作事件的支援。 若要在檢視中重新啟用操作事件,請呼叫 UIElement.TryStartDirectManipulation。

建立捲動檢視器

WinUI 3 圖庫圖示 WinUI 3 圖庫應用程式包含互動式的 WinUI 控制項與功能範例。 你可以從 Microsoft Store下載 App,或在 GitHub 瀏覽原始碼。

捲動檢視器控制項可用來讓內容捲動,方法是在捲動檢視器中明確讓內容換行,或將捲動檢視器放在內容控制項的控制項範本中。

控制項範本中的捲動檢視器

捲動檢視器控制項通常是其他控制項中的複合部分。 當主控制項的版面配置空間設限為小於展開的內容大小時,捲動檢視器元件才會顯示包含捲軸的檢視區。

ItemsView 的範本中包含 ScrollView 控制項。 你可以透過 ScrollView 屬性來訪問 ItemsView.ScrollView。

ListView 和 GridView 範本一律包含 ScrollViewer。 TextBox 和 RichEditBox 的範本也包含 ScrollViewer。 為了影響內建 ScrollViewer 元件的某些行為和屬性,ScrollViewer 會定義一系列 XAML 附加屬性,以便在樣式中設定及用於範本繫結。 有關附加屬性的詳細資訊,請參閱附加屬性概觀。

設定可捲動的內容

捲動檢視器中的內容大於捲動檢視器的檢視區時,就會變成可捲動

本範例會將 Rectangle 設定為 ScrollView 控制項的內容。 使用者只會看到矩形的 500x400 部分,但可以捲動查看其餘部分。

<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>

版面配置

在上一個範例中,矩形的大小明確設定為大於捲動檢視器。 如果捲動檢視器內容設為可自然成長,例如清單或文字區塊,您可以將捲動檢視器設為可讓內容 (延伸區) 垂直、水平、雙向擴充 (或雙向都無法擴充)。

舉例來說,此文字區塊會先向水平方向擴展,直到父容器限制其寬度,然後再換行並向垂直方向擴展。

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

如果文字區塊包裹在捲動檢視器內時,捲動檢視器會限制區塊的水平和垂直擴充。

垂直表示內容會受到水平方向的限制,但可以垂直方向成長至檢視區界限之外,而使用者則可以上下捲動內容。

一個延伸至檢視區以外的文字區塊,顯示垂直滾動條。

水平表示內容會受到垂直方向的限制,但可以水平方向成長至檢視區界限之外,而使用者則可以左右捲動內容。

超出檢視區或控件可見區域水準延伸的文字區塊,會顯示水平滾動條。

捲軸可見度

ScrollViewer 和 ScrollView 控制項設定內容的水平和垂直捲動時,使用的方法稍有不同。

下表說明這些屬性的可見性選項。

價值觀 Description
Auto 檢視區無法顯示所有內容時,捲軸才會顯示。
停用 (僅限 ScrollViewer) 即使檢視區無法顯示所有內容,捲軸也不會顯示。 透過使用者互動進行捲動的功能已停用。 (以程式控制的方式捲動仍然可行。)
隱藏 即使檢視區無法顯示所有內容,捲軸也不會顯示。 捲動仍然啟用,而且可以透過觸控、鍵盤或滑鼠滾輪互動來執行。
可見 捲軸一律會顯示。 (在目前的 UX 設計中,除非檢視區無法顯示所有內容,否則捲軸只會在滑鼠游標暫留於上方時才會顯示。)

(ScrollViewer 使用 ScrollBarVisibility 列舉;ScrollView 使用 ScrollingScrollBarVisibility 列舉。)

導覽

ScrollView 控制項有一個 ContentOrientation 屬性,可以讓你控制內容的版面。 這個屬性會決定內容未經明確限制時的擴充方式。 如果對內容明確設定 Height 和 Width,ContentOrientation 就沒有任何作用。

下表顯示 ContentOrientation 的 選項,以及 ScrollViewer 的同等設定。

導覽 ScrollView (滾動視圖) 滾動查看器
垂直 ContentOrientation="Vertical" VerticalScrollBarVisibility="[Auto][Visible][Hidden]"
HorizontalScrollBarVisibility="Disabled"
水平 ContentOrientation="Horizontal" VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="[Auto][Visible][Hidden]"
Both ContentOrientation="Both" VerticalScrollBarVisibility="[Auto][Visible][Hidden]"
HorizontalScrollBarVisibility="[Auto][Visible][Hidden]"
None 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,並且正在以水平方式排列其項目。 捲動檢視器設定已變更為支援水平捲動並停用垂直捲動。

ScrollView的 ContentOrientation 屬性設為 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>

程式設計式捲動

捲動檢視器的 offset 屬性為唯讀,但可透過程式設計方式來捲動。

使用 ScrollView 控制項時,可呼叫 ScrollTo 方法,傳遞要捲動的水平和垂直位移值。 在此情況下,您只能垂直捲動,因此需使用目前的 HorizontalOffset 值。 若要捲動至頂端,使用的 VerticalOffset 需為 0。 若要捲動到底部,VerticalOffset 與 ScrollableHeight 相同。

<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>

在此情況下,影像不受捲動限制器限制,因此一開始會顯示為原生大小。 如果影像來源大於檢視區,使用者必須縮小才能查看整個影像,而這可能不是原本預期的行為。

畫面中一幅山的圖像被放大,放大到只剩左上角的藍天和雲層可見。

下個範例示範如何設定捲動檢視器,將影像限制在檢視區,讓它最初載入時縮小,而使用者可以視需要放大和捲動。

一張山的圖片放大,使前景、山地和天空都可見。

若要將影像限制在 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 方法,允許您從目前的縮放層級依據指定的增量進行放大或縮小。