Поделиться через


ScrollView

Просмотрите пример. Обзор примера

Мультиплатформенный пользовательский интерфейс приложения .NET (.NET MAUI) ScrollView — это представление, которое может прокручивать его содержимое. По умолчанию ScrollView прокручивает содержимое по вертикали. У одного ScrollView дочернего элемента может быть только один дочерний объект, хотя это могут быть другие макеты.

ScrollView определяет следующие свойства:

  • Content, тип View, представляет содержимое, отображаемое в элементе ScrollView.
  • ContentSizeSizeТип , представляет размер содержимого. Это свойство доступно только для чтения.
  • HorizontalScrollBarVisibility, тип ScrollBarVisibility, представляет, когда горизонтальная полоса прокрутки видна.
  • Orientation, тип ScrollOrientation, представляет направление ScrollViewпрокрутки объекта . Значение по умолчанию этого свойства равно Vertical.
  • ScrollXТип , указывает текущую позицию прокрутки doubleX. Значение по умолчанию этого свойства только для чтения равно 0.
  • ScrollYdoubleТип , указывает текущую позицию прокрутки Y. Значение по умолчанию этого свойства только для чтения равно 0.
  • VerticalScrollBarVisibility, тип ScrollBarVisibility, представляет, когда вертикальная полоса прокрутки видна.

Эти свойства поддерживаются BindableProperty объектами, за исключением Content свойства, что означает, что они могут быть целевыми объектами привязки данных и стилем.

Свойство Content является ContentProperty классом ScrollView , поэтому не требуется явно задавать из XAML.

Предупреждение

ScrollView Объекты не должны быть вложенными. Кроме того, ScrollView объекты не должны быть вложенными с другими элементами управления, обеспечивающими прокрутку, например CollectionView, ListViewи WebView.

ScrollView в качестве корневого макета

У одного ScrollView дочернего элемента может быть только один дочерний объект, который может быть другим макетом. Поэтому для корневого макета на странице обычно ScrollView используется корневой макет. Чтобы прокрутить дочернее содержимое, ScrollView вычисляет разницу между высотой его содержимого и собственной высотой. Это различие заключается в том, что объем, который ScrollView может прокручивать его содержимое.

Часто StackLayout это будет ребенок.ScrollView В этом сценарии причина StackLayout того, ScrollView что сумма высоты его дочерних элементов должна быть такой же высокой. 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>
                    <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 значение, которое использует привязываемый макет для отображения Colors полей, определенных .NET MAUI. По умолчанию прокрутка 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, "Color");

            Label label = new Label
            {
                FontSize = 24,
                VerticalOptions = LayoutOptions.Center
            };
            label.SetBinding(Label.TextProperty, "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 в качестве дочернего макета

Может ScrollView быть дочерним макетом другого родительского макета.

Часто ScrollView это будет ребенок.Grid Требуется ScrollView определенная высота для вычисления разницы между высотой его содержимого и собственной высотой, а разница заключается в том, что объем, который ScrollView может прокручивать его содержимое. ScrollView Когда ребенок Gridребенка, он не получает определенную высоту. Он Grid хочет ScrollView быть как можно короче, что является либо высотой содержимого ScrollView , либо нулем. Чтобы справиться с этим сценарием, строка, RowDefinition Grid содержащая ScrollView значение , должна быть задана *. Это приведет Grid к тому, чтобы дать ScrollView все дополнительное пространство, которое не требуется другим детям, а 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="FillAndExpand"
                    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>

В этом примере корневой макет — это Grid структура с дочерним элементом LabelScrollViewи Button дочерними элементами. Он 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;
    }
}

Ориентация

ScrollViewOrientation имеет свойство, представляющее направление прокрутки объектаScrollView. Это свойство имеет тип ScrollOrientation, который определяет следующие элементы:

  • Vertical указывает, что ScrollView будет прокручиваться по вертикали. Этот элемент является значением Orientation по умолчанию свойства.
  • Horizontal указывает, что ScrollView будет прокручиваться по горизонтали.
  • Both указывает, что ScrollView будет прокручиваться по горизонтали и по вертикали.
  • Neither указывает, что ScrollView не будет прокручиваться.

Совет

Прокрутка может быть отключена Orientation , задав для свойства значение Neither.

Обнаружение прокрутки

ScrollViewScrolled определяет событие, которое вызывается, чтобы указать, что произошла прокрутка. Объект ScrolledEventArgs , который сопровождает Scrolled событие, имеет ScrollX и ScrollY свойства, оба типа double.

Внимание

ScrolledEventArgs.ScrollY Свойства ScrolledEventArgs.ScrollX могут иметь отрицательные значения из-за эффекта отскоки, которое происходит при прокрутке назад к началуScrollView.

В следующем примере XAML показан ScrollView обработчик событий для Scrolled события:

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

Эквивалентный код на C# выглядит так:

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

В этом примере OnScrollViewScrolled обработчик событий выполняется при Scrolled срабатывании события:

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.

Прокрутка позиции в представление

Позиция внутри объекта ScrollView может быть прокручена ScrollToAsync до метода, который принимает double x и y аргументы. Учитывая вертикальный ScrollView объект с именем scrollView, в следующем примере показано, как прокрутить до 150 независимых от устройства единиц из верхней части ScrollView:

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

Третий аргумент — это аргументScrollToAsync, который определяет, отображается ли анимация прокрутки при программной прокруткеScrollView.animated

Прокрутка элемента в представление

Элемент внутри объекта ScrollView можно прокрутить в представление с ScrollToAsync помощью метода, который принимает Element и ScrollToPosition аргументы. Учитывая вертикальную ScrollView и scrollViewименованную Label label, в следующем примере показано, как прокрутить элемент в представление:

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

Третий аргумент — это аргументScrollToAsync, который определяет, отображается ли анимация прокрутки при программной прокруткеScrollView.animated

При прокрутке элемента в представлении точное положение элемента после завершения прокрутки можно задать со вторым аргументом positionScrollToAsync метода. Этот аргумент принимает ScrollToPosition член перечисления:

  • MakeVisible указывает, что элемент должен быть прокручен до тех пор, пока он не отображается в элементе ScrollView.
  • Start указывает, что элемент должен быть прокручен до начала ScrollView.
  • Center указывает, что элемент должен быть прокручен в центр элемента ScrollView.
  • End указывает, что элемент должен быть прокручен до конца элемента ScrollView.

Видимость полосы прокрутки

ScrollViewHorizontalScrollBarVisibility определяет и VerticalScrollBarVisibility свойства, которые поддерживаются привязываемыми свойствами. Эти свойства получают или задают ScrollBarVisibility значение перечисления, представляющее, отображается ли горизонтальная или вертикальная полоса прокрутки. Перечисление ScrollBarVisibility определяет следующие члены:

  • Default указывает поведение полосы прокрутки по умолчанию для платформы и является значением HorizontalScrollBarVisibility по умолчанию для и VerticalScrollBarVisibility свойств.
  • Always указывает, что полосы прокрутки будут видимыми, даже если содержимое помещается в представление.
  • Never указывает, что полосы прокрутки не будут видимыми, даже если содержимое не помещается в представление.