ScrollView在Maui中的StackLayout中无法滚动的解决方法

huangapple go评论68阅读模式
英文:

Workaround for ScrollView not scrolling inside a StackLayout in Maui

问题

我有一个页面,其中在一个ScrollView内显示了一个CollectionView中的项目列表。我希望用户能够通过点击“添加”按钮或点击页面顶部的图像来向此列表添加新项目。我首先尝试使用下面显示的视图层次结构。下面的代码是真实代码的缩写版本。我发现将ScrollView放在VerticalStackLayout内会破坏Maui中的滚动功能!这里是已报告的错误。

我尝试删除ScrollView之前的VerticalStackLayout,但滚动仍然无法工作。

<ContentPage.Content>

<VerticalStackLayout>
    <VerticalStackLayout HorizontalOptions="Center">
        <Image Source="add.png">
           <ImageGestureRecongnizers>
               <TapGestureRecognizer... 用于向MyCollection添加新项目的代码...]/>
           </ImageGestureRecognizers>
        </Image>
    </VerticalStackLayout>
    <ScrollView>
        <CollectionView ItemsSource="{Binding MyCollection}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    [用于显示MyCollection中项目的布局...]
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </ScrollView>
<VerticalStackLayout>


</ContentPage.Content>

我非常感谢关于解决方案的建议,以允许查看可滚动列表并通过点击一个对象(按钮或图像)来向列表添加项目,无论列表如何滚动,该对象始终可见在页面上。

英文:

I have a page that presents a list of items in a CollectionView within a ScrollView. I want the user to be able to add a new item to this list by hitting an "add" button or tapping an image at the top of the page. I first tried this using the hierarchy of views shown below. The code below is an abbreviated version of the real thing. I discovered that putting a ScrollView within a VerticalStackLayout breaks the scrolling in Maui! Here is the reported bug.

I tried deleting the VerticalStackLayout that precedes the ScrollView and the scrolling still doesn't work.

&lt;ContentPage.Content&gt;

&lt;VerticalStackLayout&gt;
    &lt;VerticalStackLayout HorizontalOptions=&quot;Center&quot;&gt;
        &lt;Image Source=&quot;add.png&quot;&gt;
           &lt;ImageGestureRecongnizers&gt;
               &lt;TapGestureRecognizer... Code to add new item to MyCollection...]/&gt;
           &lt;/ImageGestureRecognizers&gt;
        &lt;/Image&gt;
    &lt;/VerticalStackLayout&gt;
    &lt;ScrollView&gt;
        &lt;CollectionView ItemsSource=&quot;{Binding MyCollection}&quot;&gt;
            &lt;CollectionView.ItemTemplate&gt;
                &lt;DataTemplate&gt;
                    [Layout for displaying items in MyCollection...]
                &lt;/DataTemplate&gt;
            &lt;/CollectionView.ItemTemplate&gt;
        &lt;/CollectionView&gt;
    &lt;/ScrollView&gt;
&lt;VerticalStackLayout


&lt;/ContentPage.Content&gt;

I'd greatly appreciate suggestions on a workaround to allow the viewing of the scrollable list and adding an item to the list by tapping an object (button or image) that's always visible on the page regardless of how the list is scrolled.

答案1

得分: 0

以下是翻译好的部分:

XAML:

如果您想允许查看“可滚动列表”并通过点击图像添加项目到列表中,只需将它们包装在 [Grid](https://learn.microsoft.com/en-us/dotnet/maui/user-interface/layouts/grid?view=net-maui-7.0) 中。

```xml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiAppTest01.MainPage">

    <Grid>

        <CollectionView ItemsSource="{Binding MyCollection}">

            <CollectionView.ItemTemplate>

                <DataTemplate>

                    <VerticalStackLayout>

                        <Label Text="{Binding Name}" FontSize="Large" />


                    </VerticalStackLayout>

                </DataTemplate>

            </CollectionView.ItemTemplate>

        </CollectionView>


        <Image Source="dotnet_bot.png" HeightRequest="100" WidthRequest="100" HorizontalOptions="End" VerticalOptions="End" Margin="0,0,50,20">

            <Image.GestureRecognizers>
                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
            </Image.GestureRecognizers>

        </Image>
    </Grid>


</ContentPage>

Code-behind:

public partial class MainPage : ContentPage 
{

    public ObservableCollection<MyModel> MyCollection { get; set; }
    
    public MainPage()
    {
        InitializeComponent();

        MyCollection = new ObservableCollection<MyModel>
        {

           new MyModel{ Name="1"},

           new MyModel{ Name="2"},

         };

         BindingContext = this;
     }

    private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
    {

        for (int i = 0; i < 10; i++) {
            MyCollection.Add(new MyModel { Name = i.ToString() });
        }
        
    }
}

Model:

public class MyModel 
{
    public string Name { get; set; }
}
英文:

If you want to allow the viewing of the scrollable list and add items to the list by tapping an image, you can just wrap them with a Grid.

Here's the code snippet below for your reference:

XAML:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; 
&lt;ContentPage xmlns=&quot;http://schemas.microsoft.com/dotnet/2021/maui&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
             x:Class=&quot;MauiAppTest01.MainPage&quot;&gt;

    &lt;Grid&gt;

            &lt;CollectionView ItemsSource=&quot;{Binding MyCollection}&quot;&gt;

                &lt;CollectionView.ItemTemplate&gt;

                    &lt;DataTemplate&gt;

                        &lt;VerticalStackLayout  &gt;

                            &lt;Label Text=&quot;{Binding Name}&quot; FontSize=&quot;Large&quot; /&gt;


                        &lt;/VerticalStackLayout&gt;


                    &lt;/DataTemplate&gt;

                &lt;/CollectionView.ItemTemplate&gt;

            &lt;/CollectionView&gt;


        &lt;Image Source=&quot;dotnet_bot.png&quot; HeightRequest=&quot;100&quot; WidthRequest=&quot;100&quot; HorizontalOptions=&quot;End&quot; VerticalOptions=&quot;End&quot; Margin=&quot;0,0,50,20&quot;&gt;

            &lt;Image.GestureRecognizers&gt;
                &lt;TapGestureRecognizer Tapped=&quot;TapGestureRecognizer_Tapped&quot;/&gt;
            &lt;/Image.GestureRecognizers&gt;

        &lt;/Image&gt;
    &lt;/Grid&gt;


&lt;/ContentPage&gt;

Code-behind:

public partial class MainPage : ContentPage 
{

    public ObservableCollection&lt;MyModel&gt; MyCollection { get; set; }
    
    public MainPage()
    {
            InitializeComponent();

            MyCollection = new ObservableCollection&lt;MyModel&gt;
            {

               new MyModel{ Name=&quot;1&quot;},

               new MyModel{ Name=&quot;2&quot;},

             };

             BindingContext = this;
     }



    private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
    {

        for (int i = 0; i &lt; 10; i++) {
            MyCollection.Add(new MyModel { Name = i+&quot;&quot; });
        }
        
    }
}

Model:

    public class MyModel 
    {
        public string Name { get; set; }
    }

答案2

得分: 0

我最终通过以下方式在页面的右下角创建了一个"精致"的浮动按钮:

  • 创建一个一行的网格
  • 将CollectionView和图像放在同一行
  • 在CollectionView之后定义图像,使图像位于CollectionView的顶部

我还根据Jason的建议去掉了ScrollView。

<ContentPage.Content>

    <Grid>
        <CollectionView ItemsSource="{Binding MyCollection}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    [用于显示MyCollection中项目的布局...]
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Image Source="add.png" HeightRequest="40" HorizontalOptions="End"
            VerticalOptions="End" Margin="0,0,50,20">
           <Image.GestureRecognizers>
               <TapGestureRecognizer... 用于向MyCollection添加新项目的代码..."/>
           </Image.GestureRecognizers>
        </Image>
    </Grid>

</ContentPage.Content>
英文:

I ended up creating a "fancy" floating button on the bottom right of the page by:

  • Creating a one-row Grid
  • Putting both the CollectionView and Image in the one row
  • Defining the Image after the CollectionView so that the Image sits on top of the CollectionView

I also got rid of the ScrollView per Jason's suggestion.

&lt;ContentPage.Content&gt;

    &lt;Grid
        &lt;CollectionView ItemsSource=&quot;{Binding MyCollection}&quot;&gt;
            &lt;CollectionView.ItemTemplate&gt;
                &lt;DataTemplate&gt;
                    [Layout for displaying items in MyCollection...]
                &lt;/DataTemplate&gt;
            &lt;/CollectionView.ItemTemplate&gt;
        &lt;/CollectionView&gt;
        &lt;Image Source=&quot;add.png&quot;  HeightRequest=&quot;40&quot; HorizontalOptions=&quot;End&quot;
            VerticalOptions=&quot;End&quot; Margin=&quot;0,0,50,20&quot;&gt;
           &lt;ImageGestureRecongnizers&gt;
               &lt;TapGestureRecognizer... Code to add new item to MyCollection...]/&gt;
           &lt;/ImageGestureRecognizers&gt;
        &lt;/Image&gt;
    &lt;/Grid&gt;


&lt;/ContentPage.Content&gt;

</details>



# 答案3
**得分**: 0

以下是翻译后的代码部分:

```xml
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; 
&lt;ContentPage xmlns=&quot;http://schemas.microsoft.com/dotnet/2021/maui&quot;
         xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
         x:Class=&quot;MauiAppTest01.MainPage&quot;&gt;

&lt;Grid RowDefinitions=&quot;30,*&quot;&gt;

        &lt;CollectionView ItemsSource=&quot;{Binding MyCollection}&quot;
Grid.Row=&quot;1&quot;&gt;

            &lt;CollectionView.ItemTemplate&gt;

                &lt;DataTemplate&gt;

                    &lt;VerticalStackLayout  &gt;

                        &lt;Label Text=&quot;{Binding Name}&quot; FontSize=&quot;Large&quot; /&gt;


                    &lt;/VerticalStackLayout&gt;


                &lt;/DataTemplate&gt;

            &lt;/CollectionView.ItemTemplate&gt;

        &lt;/CollectionView&gt;


    &lt;Image Source=&quot;dotnet_bot.png&quot; HeightRequest=&quot;100&quot; WidthRequest=&quot;100&quot; 
 Margin=&quot;0,0,50,20&quot;&gt;

        &lt;Image.GestureRecognizers&gt;
            &lt;TapGestureRecognizer Tapped=&quot;TapGestureRecognizer_Tapped&quot;/&gt;
        &lt;/Image.GestureRecognizers&gt;

    &lt;/Image&gt;
&lt;/Grid&gt;


&lt;/ContentPage&gt;

请注意,代码部分已被保留,并未进行翻译。

英文:

Actually for the Xaml, this will work...

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; 
&lt;ContentPage xmlns=&quot;http://schemas.microsoft.com/dotnet/2021/maui&quot;
         xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
         x:Class=&quot;MauiAppTest01.MainPage&quot;&gt;

&lt;Grid RowDefinitions=&quot;30,*&quot;&gt;

        &lt;CollectionView ItemsSource=&quot;{Binding MyCollection}&quot;
Grid.Row=&quot;1&quot;&gt;

            &lt;CollectionView.ItemTemplate&gt;

                &lt;DataTemplate&gt;

                    &lt;VerticalStackLayout  &gt;

                        &lt;Label Text=&quot;{Binding Name}&quot; FontSize=&quot;Large&quot; /&gt;


                    &lt;/VerticalStackLayout&gt;


                &lt;/DataTemplate&gt;

            &lt;/CollectionView.ItemTemplate&gt;

        &lt;/CollectionView&gt;


    &lt;Image Source=&quot;dotnet_bot.png&quot; HeightRequest=&quot;100&quot; WidthRequest=&quot;100&quot; 
 Margin=&quot;0,0,50,20&quot;&gt;

        &lt;Image.GestureRecognizers&gt;
            &lt;TapGestureRecognizer Tapped=&quot;TapGestureRecognizer_Tapped&quot;/&gt;
        &lt;/Image.GestureRecognizers&gt;

    &lt;/Image&gt;
&lt;/Grid&gt;

</ContentPage>

Adjust your RowDefinition(30) for the image!
Sorry if my code is not neat, as I'm on mobile.

huangapple
  • 本文由 发表于 2023年2月16日 05:24:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75465567.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定