4

I am trying to disable scrolling in my collection view. The reason why I want to do that is there is a scroll view already in my XAML code. When I try to scroll all page elements on the page, collection view elements are also scrolled themselves but I don't want that.

 <ScrollView>
        <StackLayout  Padding="20" Spacing="20" >
            <Frame CornerRadius="15" 
                   BackgroundColor="#A6EDB3" 
                   VerticalOptions="StartAndExpand"
                   HeightRequest="200" 
                   IsClippedToBounds="True"
                   Padding="0"   >
                <StackLayout Padding="10,5,10,5"   
                             Orientation="Horizontal"   >
                    <Image Source="settingsIcon"  
                               HeightRequest="25" 
                               WidthRequest="25" 
                               Aspect="Fill" />
                    <Label Text="Filter" 
                               FontSize="Medium" 
                               VerticalTextAlignment="Center" 
                               VerticalOptions="Center"/>
                </StackLayout>
            </Frame>
            <Label Text="Vocabulary topics" TextColor="black" FontSize="20" FontAttributes="Bold" ></Label>
            <CollectionView    x:Name="topics" Scrolled="topics_Scrolled" VerticalScrollBarVisibility="Never" >
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout Padding="0,10,0,10">
                            <Frame HasShadow="False"
                                       HeightRequest="60"
                                       CornerRadius="15" 
                                       BackgroundColor="{Binding BackgroundColor}" 
                                       HorizontalOptions="Fill" >
                                <StackLayout Orientation="Horizontal">
                                    <Frame BackgroundColor="{Binding BoxColor}" WidthRequest="40" ></Frame>
                                    <StackLayout>
                                        <Label Text="{Binding Name}"></Label>
                                    </StackLayout>
                                </StackLayout>
                            </Frame>
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
    </ScrollView>

on

Fatikhan Gasimov
  • 903
  • 2
  • 16
  • 40
  • Remove the scrollView and put the UI above the collection into the [header of collectionView](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/layout#headers-and-footers). – nevermore Aug 11 '20 at 05:38

2 Answers2

1

Having two scrolls on the same page is not the correct way.

Also if you just want to place items above/below your collectionView use the Header/Footer properties then!!

For instance, for the current design, your CollectionView could look something like below and work as you want it to.

 <CollectionView   Padding="20"  x:Name="topics" Scrolled="topics_Scrolled" VerticalScrollBarVisibility="Never" >
            <CollectionView.Header>
              <StackLayout  Spacing="20" >
        <Frame CornerRadius="15" 
               BackgroundColor="#A6EDB3" 
               VerticalOptions="StartAndExpand"
               HeightRequest="200" 
               IsClippedToBounds="True"
               Padding="0"   >
            <StackLayout Padding="10,5,10,5"   
                         Orientation="Horizontal"   >
                <Image Source="settingsIcon"  
                           HeightRequest="25" 
                           WidthRequest="25" 
                           Aspect="Fill" />
                <Label Text="Filter" 
                           FontSize="Medium" 
                           VerticalTextAlignment="Center" 
                           VerticalOptions="Center"/>
            </StackLayout>
        </Frame>
        <Label Text="Vocabulary topics" TextColor="black" FontSize="20" FontAttributes="Bold" ></Label>
        </StackLayout>
            </CollectionView.Header>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Padding="0,10,0,10">
                        <Frame HasShadow="False"
                                   HeightRequest="60"
                                   CornerRadius="15" 
                                   BackgroundColor="{Binding BackgroundColor}" 
                                   HorizontalOptions="Fill" >
                            <StackLayout Orientation="Horizontal">
                                <Frame BackgroundColor="{Binding BoxColor}" WidthRequest="40" ></Frame>
                                <StackLayout>
                                    <Label Text="{Binding Name}"></Label>
                                </StackLayout>
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

Note: you might have to adjust the margin and padding properties for it to look the exact same. My code is just an example.

For more information on CollectionView check: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/

FreakyAli
  • 13,349
  • 3
  • 23
  • 63
  • 1
    it's not about disabling the scroll – Ferenc Dajka Feb 08 '22 at 14:40
  • @FerencDajka Yes because the title is misleading once you read the question you will realise! – FreakyAli Feb 09 '22 at 08:54
  • I believe you totally miss the point here. he wants to be able to scroll the topics once the "filter" section disappears. he doesn't want this section to be the header of the collection view – Bryce Friha Jul 05 '22 at 10:31
  • @BryceFriha What he wanted was a common scroll that scrolled the whole filters and then the topics below it that is the whole reason he marked my answer as correct... – FreakyAli Jul 08 '22 at 07:36
  • @FreakyAli Absolutely not. And I guess he marked your answer as correct because it "does the job" but ultimately this is not necessarily what he wanted. – Bryce Friha Jul 08 '22 at 09:21
  • @BryceFriha The thing is having multiple Scrolls on a single page is a bad practice in mobile development in general... https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/scrollview So I am not sure what you mean here, I mean these are mobile development basics, and debating them and having nasty workarounds on this makes zero sense... – FreakyAli Jul 08 '22 at 09:38
  • @FreakyAli yes multiple active scrolls are bad practices. But this is not really multiple scrolls this is a header that collapses through scrolling and leaving letting another scroll take place. You can find this with many well known mobile app UI (like Binance). I think understanding why something is a bad practice in the first place is more important. – Bryce Friha Jul 08 '22 at 09:49
  • It is exactly what that is if you are talking about a Parallax effect then even that is done with just one scroll container, Having two scrollable containers in the View hierarchy is a bad practice, no doubt there! – FreakyAli Jul 08 '22 at 09:58
1

You can use InputTransparent. In your case what I would do would be to wrap the CollectionView in a <ContentView> as:

<ContentView InputTransparent="True"
              x:Name="content">
                    <CollectionView ItemsSource="{Binding Items}"...>
                    ...
                    </CollectionView>
</ContentView>

Create a scroll event to your scroll view:

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

Then, with this event, make sure that the InputTransparent switches depending on the scroll position:

private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
        {
            var scrollView = sender as ScrollView;
            // Get the height of your scroll view
            var contentSize = scrollView.ContentSize.Height; 
            
            // Get the max position of the scrollview    
            var maxPos = contentSize - scrollView.Height;
                
                // Compare it to the current position
                if (Convert.ToInt16(e.ScrollY) >= Convert.ToInt16(maxPos))
                {
                    // Switch input transparent value
                    content.InputTransparent = false;
                }
                else if (Convert.ToInt16(e.ScrollY) == 0)
                {
                    content.InputTransparent = true;
                }
        }

This is perfectly fine to use two scrollable controls on the same page for what you want to do. And I don't think <CollectionView.Header> would give you the result you want.

I hope it was helpful!

Bryce Friha
  • 186
  • 2
  • 11