.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 物件不應與其他提供捲動功能的控制項(如 CollectionView、 ListView、 WebView和 )巢狀。
ScrollView 作為根版面配置
A ScrollView 只能有一個子項,這個子項必須是其他版面配置。 因此,頁面上通常會用 a ScrollView 作為根配置。 要捲動其子內容, ScrollView 會計算其內容高度與自身高度的差值。 該差異指的是 ScrollView 能夠捲動其內容的範圍。
A StackLayout 通常是 ScrollView 的子節點。 在這種情況下,ScrollView 會使 StackLayout 的高度等同於其子元素的高度總和。 接著ScrollView可以決定其內容可以被捲動多少。 欲了解更多相關 StackLayout資訊,請參見 StackLayout。
謹慎
在垂直 ScrollView中,避免將屬性設 VerticalOptions 為 Start、 Center或 End。 這樣做會讓 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 會垂直捲動,以顯示更多內容。
對等的 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 可捲動內容的程度。 當 ScrollView 是 Grid 的子節點時,它不會被指定特定的高度。
Grid 希望 ScrollView 盡可能地短,要麼是 ScrollView 內容的高度,要麼是零。 為了處理此情境,應將包含ScrollView的Grid列中的RowDefinition設為*。 這樣會讓其他GridScrollView孩子獲得不需要的額外空間,ScrollView並擁有特定的高度。
以下 XAML 範例中,ScrollView 是 Grid 的子佈局:
<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,其子節點為 Label、 ScrollViewButton 和 。 ScrollView 的內容是 StackLayout,而 StackLayout 則包含多個 Label 物件。 這種排列確保第一個 Label 物件總是在螢幕上,而其他 Label 物件顯示的文字則可以滾動:
對等的 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的物件具有 ScrollX 和 ScrollY 屬性,兩者皆為類型 double。
這很重要
ScrolledEventArgs.ScrollX和ScrolledEventArgs.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方法不會導致捲動。
將某個位置滾動到視圖中
使用接受 double、x 和 y 參數的方法,可以捲動到ScrollToAsyncScrollView中的位置。 給定一個名為 ScrollView的垂直scrollView物件,以下範例展示如何從 頂部ScrollView捲動至 150 個裝置無關單位:
await scrollView.ScrollToAsync(0, 150, true);
第三個 ScrollToAsync 參數是 animated 參數,決定是否在 ScrollView 被使用程式碼捲動時顯示捲動畫。
將元素捲動至可視範圍
ScrollView中的元素可以使用ScrollToAsync方法捲動到可見範圍內,該方法接受Element和ScrollToPosition作為參數。 給定一個垂直的ScrollView名為scrollView,以及一個Label名為label的元素,以下範例展示如何將某元素捲入檢視範圍內:
await scrollView.ScrollToAsync(label, ScrollToPosition.End, true);
第三個ScrollToAsync是animated參數,決定以程式方式捲動ScrollView時是否會顯示捲動動畫。
當將元素捲入視圖時,可以用該方法的position第二個參數 ScrollToAsync,設定該元素在捲動完成後的精確位置。 此引數接受一個 ScrollToPosition 列舉成員:
-
MakeVisible表示該元素應滾動直到在 ScrollView 中可見。 -
Start表示該元素應捲動至 ScrollView 的開始。 -
Center表示該元素應被捲動到 ScrollView中心。 -
End表示該元素應捲動至末尾 ScrollView。
捲軸可見性
ScrollView
HorizontalScrollBarVisibility定義與VerticalScrollBarVisibility屬性,這些屬性由可綁定的屬性所支撐。 這些屬性會取得或設定一個 ScrollBarVisibility 枚舉值,代表橫向還是垂直捲動條是否可見。
ScrollBarVisibility 列舉定義了下列成員:
-
Default表示該平台的預設捲動列行為,是HorizontalScrollBarVisibility和VerticalScrollBarVisibility屬性的預設值。 -
Always表示即使內容已完全符合視窗大小,捲動條仍會顯示。 -
Never表示即使內容不合適於檢視圖,捲動條也不會顯示。
瀏覽範例