当 ContentPage 中有两个 CollectionViews 时滚动

问题描述

我的 ContentPage 在 StackLayout 中有两个 CollectionViews,一个在另一个之上。每个都绑定到单独的 ItemsSource。在每个上面我都有一个标签。此时每一个都占屏幕的 50% 并单独滚动。

我希望所有内容都滚动起来,就好像它是一个长列表一样。

所以我用 ScrollView 包围了所有东西。但是,根据您放置手指的位置,滚动可能会滚动整个页面(这正是我想要的)或仅滚动当前 CollectionView。

似乎没有办法取消 CollectionView 的滚动功能。真的吗?如果没有,我应该如何设置我的 ContentPage ?

在下面的示例中,两个 CollectionViews 具有相同的模型和绑定,但实际上它们会有所不同。

这里是xaml:

<RefreshView
        x:DataType="local:AllRestaurantsviewmodel"
        Command="{Binding LoadItemsCommand}"
        IsRefreshing="{Binding IsBusy,Mode=TwoWay}">
        <ScrollView>
            <StackLayout>
                <Label
                    FontSize="Large"
                    HorizontalOptions="Center"
                    Text="Suggested Restaurants" />
                <CollectionView
                    x:Name="ItemsListView"
                    ItemsSource="{Binding SuggestedRestsComments}"
                    SelectionMode="None">
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <StackLayout Padding="10" x:DataType="model:SuggestedRestsComment">
                                <Label
                                    FontSize="16"
                                    LineBreakMode="Nowrap"
                                    Style="{DynamicResource ListItemTextStyle}"
                                    Text="{Binding restaurantName}" />
                                <Label
                                    FontSize="13"
                                    LineBreakMode="Nowrap"
                                    Style="{DynamicResource ListItemDetailTextStyle}"
                                    Text="{Binding CityName}" />
                                <StackLayout.GestureRecognizers>
                                    <TapGestureRecognizer
                                        Command="{Binding Source={RelativeSource AncestorType={x:Type local:Itemsviewmodel}},Path=ItemTapped}"
                                        CommandParameter="{Binding .}"
                                        NumberOfTapsrequired="1" />
                                </StackLayout.GestureRecognizers>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>


                <Label
                    FontSize="Large"
                    HorizontalOptions="Center"
                    Text="Existing Restaurants" />


                <CollectionView
                    x:Name="ItemsListView2"
                    ItemsSource="{Binding SuggestedRestsComments}"
                    SelectionMode="None">
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <StackLayout Padding="10" x:DataType="model:SuggestedRestsComment">
                                <Label
                                    FontSize="16"
                                    LineBreakMode="Nowrap"
                                    Style="{DynamicResource ListItemTextStyle}"
                                    Text="{Binding restaurantName}" />
                                <Label
                                    FontSize="13"
                                    LineBreakMode="Nowrap"
                                    Style="{DynamicResource ListItemDetailTextStyle}"
                                    Text="{Binding CityName}" />
                                <StackLayout.GestureRecognizers>
                                    <TapGestureRecognizer
                                        Command="{Binding Source={RelativeSource AncestorType={x:Type local:Itemsviewmodel}},Path=ItemTapped}"
                                        CommandParameter="{Binding .}"
                                        NumberOfTapsrequired="1" />
                                </StackLayout.GestureRecognizers>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </StackLayout>
        </ScrollView>
    </RefreshView>

解决方法

这个怎么样?

在您的滚动视图中设置 InputTransparent="True" 这允许输入通过下面的层。

<ScrollView InputTransparent="True">

然后在集合视图的右侧留下一些空白(背景)。

现在,当有人在空白处滑动时,整个页面都会滚动。当有人在集合视图内滑动时,集合视图会滚动。

,

您可以尝试使用 Custom CollectionViewRenderer 在每个平台上实现这一点。

例如,在表单中发送消息:

void OnButtonClicked(object sender,EventArgs e)
{
    MessagingCenter.Send<object>(this,"StopScrollinng");
}

然后在 iOS CustomCollectionViewRenderer 类中停止滚动:

public class CustomCollectionViewRenderer: CollectionViewRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<GroupableItemsView> e)
    {
        base.OnElementChanged(e);

        MessagingCenter.Subscribe<object>(this,"StopScrollinng",(sender) =>
        {
            // Do something whenever the "StopScrollinng" message is received
            if (Control != null)
            {
                NSArray s = Control.ValueForKey(new NSString("_subviewCache")) as NSMutableArray;
                UICollectionView c = s.GetItem<UICollectionView>(0);
                c.SetContentOffset(c.ContentOffset,true);
            }
        });
    }
}

Android CustomCollectionViewRenderer 类中停止滚动:

public class CustomCollectionViewRenderer: CollectionViewRenderer
{
    public CustomCollectionViewRenderer(Context context) : base(context)
    {
       
    }

    protected override void OnElementChanged(ElementChangedEventArgs<ItemsView> elementChangedEvent)
    {
        base.OnElementChanged(elementChangedEvent);
        MessagingCenter.Subscribe<object>(this,(sender) =>
        {
            // Do something whenever the "StopScrollinng" message is received

            this.DispatchTouchEvent(MotionEvent.Obtain(SystemClock.UptimeMillis(),SystemClock.UptimeMillis(),MotionEventActions.Cancel,0));
        });
    }
}