ScrollView (滾動視圖)

瀏覽範例。 瀏覽範例

.NET 多平台應用程式介面(.NET MAUI) ScrollView 是一個能夠滾動內容的檢視方式。 預設情況下,內容 ScrollView 會垂直捲動。 A ScrollView 只能有單一子,雖然這可以是其他版面配置。

ScrollView 定義下列屬性:

  • Content 的型別為 View,代表要在 ScrollView 中顯示的內容。
  • ContentSize,型別 Size為 ,代表內容的大小。 這是唯讀屬性。
  • HorizontalScrollBarVisibility 類型為 ScrollBarVisibility,用於表示水平捲軸可見時。
  • Orientation,屬於ScrollOrientation型別,代表ScrollView的滾動方向。 這個屬性預設值為 Vertical
  • ScrollX 的型別是 double,表示目前的 X 滾動位置。 此唯讀屬性的預設值為 0。
  • ScrollY 型別為 double,表示當前的 Y 捲動位置。 此唯讀屬性的預設值為 0。
  • VerticalScrollBarVisibility,型別 ScrollBarVisibility為 ,代表垂直捲動條可見的時間。

這些屬性由 BindableProperty 物件支持,唯獨屬性 Content 除外,這表示它們可以作為資料綁定的目標,並以樣式方式進行。

Content屬性是ScrollView類別的ContentProperty,因此不需要從 XAML 中顯式設定。

警告

ScrollView 物件不應該巢狀。 此外, ScrollView 物件不應與其他提供捲動功能的控制項(如 CollectionViewListViewWebView和 )巢狀。

ScrollView 作為根版面配置

A ScrollView 只能有一個子項,這個子項必須是其他版面配置。 因此,頁面上通常會用 a ScrollView 作為根配置。 要捲動其子內容, ScrollView 會計算其內容高度與自身高度的差值。 該差異指的是 ScrollView 能夠捲動其內容的範圍。

A StackLayout 通常是 ScrollView 的子節點。 在這種情況下,ScrollView 會使 StackLayout 的高度等同於其子元素的高度總和。 接著ScrollView可以決定其內容可以被捲動多少。 欲了解更多相關 StackLayout資訊,請參見 StackLayout

謹慎

在垂直 ScrollView中,避免將屬性設 VerticalOptionsStartCenterEnd。 這樣做會讓 ScrollView 的高度達到所需的水平,甚至可能是零。 雖然 .NET MAUI 能防止這種情況發生,但最好避免使用暗示你不希望發生的程式碼。

以下 XAML 範例在頁面中以 ScrollView 作為根佈局:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ScrollViewDemos"
             x:Class="ScrollViewDemos.Views.XAML.ColorListPage"
             Title="ScrollView demo">
    <ScrollView Margin="20">
        <StackLayout BindableLayout.ItemsSource="{x:Static local:NamedColor.All}">
            <BindableLayout.ItemTemplate>
                <DataTemplate x:DataType="local:NamedColor">
                    <StackLayout Orientation="Horizontal">
                        <BoxView Color="{Binding Color}"
                                 HeightRequest="32"
                                 WidthRequest="32"
                                 VerticalOptions="Center" />
                        <Label Text="{Binding FriendlyName}"
                               FontSize="24"
                               VerticalOptions="Center" />
                    </StackLayout>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </ScrollView>
</ContentPage>

在這個例子中,ScrollView 的內容被設定為一個使用可綁定版面的 StackLayout,用來顯示由 .NET MAUI 定義的 Colors 欄位。 預設情況下,ScrollView 會垂直捲動,以顯示更多內容。

根目錄 ScrollView 佈局的截圖。

對等的 C# 程式代碼為:

public class ColorListPage : ContentPage
{
    public ColorListPage()
    {
        DataTemplate dataTemplate = new DataTemplate(() =>
        {
            BoxView boxView = new BoxView
            {
                HeightRequest = 32,
                WidthRequest = 32,
                VerticalOptions = LayoutOptions.Center
            };
            boxView.SetBinding(BoxView.ColorProperty, static (NamedColor nc) => nc.Color);

            Label label = new Label
            {
                FontSize = 24,
                VerticalOptions = LayoutOptions.Center
            };
            label.SetBinding(Label.TextProperty, static (NamedColor nc) => nc.FriendlyName);

            StackLayout horizontalStackLayout = new StackLayout
            {
                Orientation = StackOrientation.Horizontal
            };
            horizontalStackLayout.Add(boxView);
            horizontalStackLayout.Add(label);

            return horizontalStackLayout;
        });

        StackLayout stackLayout = new StackLayout();
        BindableLayout.SetItemsSource(stackLayout, NamedColor.All);
        BindableLayout.SetItemTemplate(stackLayout, dataTemplate);

        ScrollView scrollView = new ScrollView
        {
            Margin = new Thickness(20),
            Content = stackLayout
        };

        Title = "ScrollView demo";
        Content = scrollView;
    }
}

欲了解更多可綁定版面的資訊,請參見 BindableLayout

ScrollView 作為子佈局

A ScrollView 可以是屬於不同父布局的子布局。

ScrollView 通常是 Grid 的子節點。 A ScrollView 需要具備特定的高度來計算其中的內容高度與自身高度的差異,這個差異即為 ScrollView 可捲動內容的程度。 當 ScrollViewGrid 的子節點時,它不會被指定特定的高度。 Grid 希望 ScrollView 盡可能地短,要麼是 ScrollView 內容的高度,要麼是零。 為了處理此情境,應將包含ScrollViewGrid列中的RowDefinition設為*。 這樣會讓其他GridScrollView孩子獲得不需要的額外空間,ScrollView並擁有特定的高度。

以下 XAML 範例中,ScrollViewGrid 的子佈局:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ScrollViewDemos.Views.XAML.BlackCatPage"
             Title="ScrollView as a child layout demo">
    <Grid Margin="20"
          RowDefinitions="Auto,*,Auto">
        <Label Text="THE BLACK CAT by Edgar Allan Poe"
               FontSize="14"
               FontAttributes="Bold"
               HorizontalOptions="Center" />
        <ScrollView x:Name="scrollView"
                    Grid.Row="1"
                    VerticalOptions="Fill"
                    Scrolled="OnScrollViewScrolled">
            <StackLayout>
                <Label Text="FOR the most wild, yet most homely narrative which I am about to pen, I neither expect nor solicit belief. Mad indeed would I be to expect it, in a case where my very senses reject their own evidence. Yet, mad am I not -- and very surely do I not dream. But to-morrow I die, and to-day I would unburthen my soul. My immediate purpose is to place before the world, plainly, succinctly, and without comment, a series of mere household events. In their consequences, these events have terrified -- have tortured -- have destroyed me. Yet I will not attempt to expound them. To me, they have presented little but Horror -- to many they will seem less terrible than barroques. Hereafter, perhaps, some intellect may be found which will reduce my phantasm to the common-place -- some intellect more calm, more logical, and far less excitable than my own, which will perceive, in the circumstances I detail with awe, nothing more than an ordinary succession of very natural causes and effects." />
                <!-- More Label objects go here -->
            </StackLayout>
        </ScrollView>
        <Button Grid.Row="2"
                Text="Scroll to end"
                Clicked="OnButtonClicked" />
    </Grid>
</ContentPage>

在此範例中,根配置為 aGrid,其子節點為 LabelScrollViewButton 和 。 ScrollView 的內容是 StackLayout,而 StackLayout 則包含多個 Label 物件。 這種排列確保第一個 Label 物件總是在螢幕上,而其他 Label 物件顯示的文字則可以滾動:

子 ScrollView 佈局的截圖。

對等的 C# 程式代碼為:

public class BlackCatPage : ContentPage
{
    public BlackCatPage()
    {
        Label titleLabel = new Label
        {
            Text = "THE BLACK CAT by Edgar Allan Poe",
            // More properties set here to define the Label appearance
        };

        StackLayout stackLayout = new StackLayout();
        stackLayout.Add(new Label { Text = "FOR the most wild, yet most homely narrative which I am about to pen, I neither expect nor solicit belief. Mad indeed would I be to expect it, in a case where my very senses reject their own evidence. Yet, mad am I not -- and very surely do I not dream. But to-morrow I die, and to-day I would unburthen my soul. My immediate purpose is to place before the world, plainly, succinctly, and without comment, a series of mere household events. In their consequences, these events have terrified -- have tortured -- have destroyed me. Yet I will not attempt to expound them. To me, they have presented little but Horror -- to many they will seem less terrible than barroques. Hereafter, perhaps, some intellect may be found which will reduce my phantasm to the common-place -- some intellect more calm, more logical, and far less excitable than my own, which will perceive, in the circumstances I detail with awe, nothing more than an ordinary succession of very natural causes and effects." });
        // More Label objects go here

        ScrollView scrollView = new ScrollView();
        scrollView.Content = stackLayout;
        // ...

        Title = "ScrollView as a child layout demo";
        Grid grid = new Grid
        {
            Margin = new Thickness(20),
            RowDefinitions =
            {
                new RowDefinition { Height = new GridLength(0, GridUnitType.Auto) },
                new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
                new RowDefinition { Height = new GridLength(0, GridUnitType.Auto) }
            }
        };
        grid.Add(titleLabel);
        grid.Add(scrollView, 0, 1);
        grid.Add(button, 0, 2);

        Content = grid;
    }
}

導覽

ScrollView 有一個 Orientation 性質,代表 的 ScrollView滾動方向。 此性質型別為 ScrollOrientation,定義了以下成員:

  • Vertical 表示 ScrollView 將會垂直捲動。 此成員即為該財產的 Orientation 預設價值。
  • Horizontal 表示 ScrollView 將會橫向滾動。
  • Both 表示 ScrollView 將進行橫向及垂直的捲動。
  • Neither 表示 ScrollView 不會捲動。

小提示

可透過將屬性Orientation設定Neither為 來停用捲動。

偵測捲動

ScrollView 定義了一個 Scrolled 事件,表示捲動已發生。 ScrolledEventArgs伴隨事件Scrolled的物件具有 ScrollXScrollY 屬性,兩者皆為類型 double

這很重要

ScrolledEventArgs.ScrollXScrolledEventArgs.ScrollY屬性可能為負值,因為當捲回 a ScrollView的起點時會產生反彈效應。

以下 XAML 範例展示了一個 ScrollView,用於為 Scrolled 事件設定事件處理器。

<ScrollView Scrolled="OnScrollViewScrolled">
    ...
</ScrollView>

對等的 C# 程式代碼為:

ScrollView scrollView = new ScrollView();
scrollView.Scrolled += OnScrollViewScrolled;

在此範例中,當 Scrolled 事件觸發時,會執行 OnScrollViewScrolled 事件處理程序。

void OnScrollViewScrolled(object sender, ScrolledEventArgs e)
{
    Console.WriteLine($"ScrollX: {e.ScrollX}, ScrollY: {e.ScrollY}");
}

在此範例中, OnScrollViewScrolled 事件處理器會輸出伴隨事件的 ScrolledEventArgs 物件值。

備註

Scrolled事件將會在使用者發起的滾動事件以及程式化滾動事件中觸發。

程式式捲動

ScrollView定義了兩種ScrollToAsync方法,這些方法會非同步捲動ScrollView。 其中一個多載會將 ScrollView 捲動至指定位置,另一個則將指定元素捲動至可視區域。 這兩種超載都有額外的參數,可以用來指示是否要讓捲軸動畫。

這很重要

當屬性ScrollToAsync設為 ScrollView.Orientation時,這些Neither方法不會導致捲動。

將某個位置滾動到視圖中

使用接受 doublexy 參數的方法,可以捲動到ScrollToAsyncScrollView中的位置。 給定一個名為 ScrollView的垂直scrollView物件,以下範例展示如何從 頂部ScrollView捲動至 150 個裝置無關單位:

await scrollView.ScrollToAsync(0, 150, true);

第三個 ScrollToAsync 參數是 animated 參數,決定是否在 ScrollView 被使用程式碼捲動時顯示捲動畫。

將元素捲動至可視範圍

ScrollView中的元素可以使用ScrollToAsync方法捲動到可見範圍內,該方法接受ElementScrollToPosition作為參數。 給定一個垂直的ScrollView名為scrollView,以及一個Label名為label的元素,以下範例展示如何將某元素捲入檢視範圍內:

await scrollView.ScrollToAsync(label, ScrollToPosition.End, true);

第三個ScrollToAsyncanimated參數,決定以程式方式捲動ScrollView時是否會顯示捲動動畫。

當將元素捲入視圖時,可以用該方法的position第二個參數 ScrollToAsync,設定該元素在捲動完成後的精確位置。 此引數接受一個 ScrollToPosition 列舉成員:

  • MakeVisible 表示該元素應滾動直到在 ScrollView 中可見。
  • Start 表示該元素應捲動至 ScrollView 的開始。
  • Center 表示該元素應被捲動到 ScrollView中心。
  • End 表示該元素應捲動至末尾 ScrollView

捲軸可見性

ScrollView HorizontalScrollBarVisibility定義與VerticalScrollBarVisibility屬性,這些屬性由可綁定的屬性所支撐。 這些屬性會取得或設定一個 ScrollBarVisibility 枚舉值,代表橫向還是垂直捲動條是否可見。 ScrollBarVisibility 列舉定義了下列成員:

  • Default 表示該平台的預設捲動列行為,是 HorizontalScrollBarVisibilityVerticalScrollBarVisibility 屬性的預設值。
  • Always 表示即使內容已完全符合視窗大小,捲動條仍會顯示。
  • Never 表示即使內容不合適於檢視圖,捲動條也不會顯示。