Xamarin.Forms: how to automatically hide first CollectionView - xaml

I work on a Xamarin.Forms app that will contain a page with 2 CollectionView items:
an horizontal CollectionView that will display events
a vertical CollectionView that will display posts
I would like that the first list is progressively hidden as soon as the user starts to scroll on the second list.
We can found this behaviour on a sample from Syncfusion: but they use a SfRotator as control for the horizontal list:
I've tried to reproduce the same behaviour on my page, but it doesn't work as expected. My horizontal list is not hidden until I scroll vertically on this first list itself. If I scroll on the second vertical list, the first list is still visible:
My XAML looks like this:
<ContentPage.Content>
<RefreshView x:DataType="vm:NewsViewModel"
IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<ScrollView>
<StackLayout Padding="16" Spacing="16">
<CollectionView x:Name="EventsListView"
ItemsSource="{Binding Events}"
HeightRequest="250"
VerticalScrollBarVisibility="Never"
SelectionMode="None">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ctrl:ShadowFrame BackgroundColor="Red">
<StackLayout x:DataType="model:Event" >
<Label Text="{Binding Name}" />
<Image Source="{Binding Image}" />
</StackLayout>
</ctrl:ShadowFrame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView x:Name="NewsListView"
ItemsSource="{Binding News}"
VerticalScrollBarVisibility="Never"
SelectionMode="None">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ctrl:ShadowFrame>
<StackLayout x:DataType="model:News">
<Label Text="{Binding Description}" />
<Label Text="{Binding Date}" />
<Image Source="{Binding Image}" />
</StackLayout>
</ctrl:ShadowFrame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ScrollView>
</RefreshView>
</ContentPage.Content>
=> Is there a way to achieve this?

Quick reminder that you Shouldn't use Scrollable Elements inside other Scrollable Element, it usually breaks how both work, Quoting:
Xamarin doesn't recommend using the ListView, WebView, or ScrollView
inside a ScrollView. Microsoft Xamarin.Forms Official Documentation
says that ScrollViews should not be nested. In addition, ScrollViews
should not be nested with other controls that provide scrolling, like
ListView and WebView.
And this is what happening:
The ScrollView isn't actually scrolling, the Vertical CollectionView is the one giving the Illusion that the page is scrolling, meaning that the Horizontal one is always on top.
How to fix it?
To fix this, you should remove the Vertical CollectionView and use some kind of Repeater View, this Post will guide you on how to achieve it.

Related

MAUI make button resize to fit text

How can i make a button resize itself to fit the entire text. Currently i have a CollectionView that gets populated with buttons with text from a collection. The issue i have is that the button does not expand to fit the text and for all buttons generated, the width is identical. Is it possible to make each button size itself just to fit in the text within it?
<CollectionView x:Name="TagsView"
Grid.Row="0">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Button Text="{Binding Name}"
CornerRadius="15"
HorizontalOptions="CenterAndExpand"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
What it looks like at the moment:
Thanks
Firstly, if you want to make a button resize itself to fit the entire text, you need to set propeties HorizontalOptions and VerticalOptions of this button like below:
HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"
And then,you should add a LinearItemsLayout with Horizontal Orientation like below:
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>

Why is the Image.Margin in a CollectionView template not creating visual space?

We have a ListView bound to a List of objects of a type called Trial. Each Trial has a property, called Pictures, that is a List of objects of a type, Picture, that represents an image and some metadata. We are using a horizontal CollectionView within the ListView item template to display thumbnails of the images, if any. The problem is in getting a little space between the images. We've tried setting a Margin property value on the Image in the CollectionView item template, but the images are still appearing right next to each other as seen in the illustration.
This is the XAML describing the ListView:
<ListView x:Name="trialsListView"
ItemsSource="{Binding .}"
ItemTapped="Handle_ItemTapped"
CachingStrategy="RecycleElement"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20">
<Label
Text="{Binding Prompt}"
BackgroundColor="{Binding TrialType, Converter={StaticResource TrialTypeToColorConverter}}"
Padding="5" />
<Label Text="{Binding Response}" />
<CollectionView
BindingContext="{Binding Pictures}"
ItemsSource="{Binding .}"
ItemsLayout="HorizontalList"
HeightRequest="{Binding Count, Converter={StaticResource PicturesCountToHeightConverter}}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Image
HeightRequest="80"
Source="{Binding PictureName, Converter={StaticResource PictureNameToImageSourceConverter}}"
Margin="10" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And this is an example of output (from an iOS device):
I suppose we can enclose the Image in a Frame or some layout, but that feels like a 90s web hack. Surely there is a right way to get some spacing without resorting to adding screen elements? What do I not yet understand here?

How to set z-index on a control within AbsoluteLayout in xaml?

I have an AbsoluteLayout on a view in my Xamarin.Forms app, with 3 buttons in it. After another control is added programmatically, it covers the buttons. I cannot figure out how I can make the buttons to be always in front.
<ContentPage.Content>
<AbsoluteLayout x:Name="Container" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Button
Style="{StaticResource CallButtonStyle}"
...
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".85,.02"
Text="{Binding CameraSwitchIcon}" />
<Button
...
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".15,.95,80,80"
Text="{Binding VideoToggleIcon}" />
<Button
...
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".85,.95,80,80"
Text="{Binding AudioToggleIcon}" />
</AbsoluteLayout>
</ContentPage.Content>
all XF Layouts have RaiseChild() and LowerChild() methods you can use to adjust the Z index

How to get FAB to float over WebView in Xamarin XAML

I'm trying to setup a XAML form definition which shows a WebView but which has a Floating Action Button over the bottom right.
If I use an AbsoluteLayout, the FAB appears correctly over the WebView. However, due to the Height/WidthRequest of the Webview, it is displayed at full size - the text disappears off the right side and doesn't wrap, so the page doesn't scroll.
<ContentPage ...snip... Title="Document">
<StackLayout Padding="5,5,5,5" HorizontalOptions="FillAndExpand" Orientation="Vertical">
<WebView x:Name="webViewDocument" WidthRequest="1000" HeightRequest="1000" />
<Label Text="{Binding UpdatedWhen, StringFormat='Last Updated: {0:dd MMM yyyy HH:mm}'}"
VerticalTextAlignment="Center" HorizontalTextAlignment="End" FontSize="Small" />
<customControls:ImageButton x:Name="fab"
Source="{markupExtensions:PlatformImage SourceImage='IconFAB'}"
Command="{Binding AddCommand}"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.95,0.975,-1,-1"
Margin="10" />
</StackLayout>
</ContentPage>
If I use a StackLayout, the WebView sizes and scrolls correctly, however the FAB occupies a full width strip at the bottom of the screen and the text does not appear behind it - the WebView stops above it.
I've spent the last hour and a half trying every combination of nested Layout I can think of to solve this and just can't get it right - can some kind layout genius out there please tell me how I can solve this.
Thanks
Use a Grid and do not indicate rows or columns.
Something like this:
<Grid Padding="5,5,5,5"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<WebView x:Name="webViewDocument"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand" />
<Label Text="{Binding UpdatedWhen, StringFormat='Last Updated: {0:dd MMM yyyy HH:mm}'}"
VerticalOptions="End"
HorizontalOptions="Center"
HorizontalTextAlignment="End"
FontSize="Small" />
<customControls:ImageButton x:Name="fab"
Source="{markupExtensions:PlatformImage SourceImage='IconFAB'}"
Command="{Binding AddCommand}"
VerticalOptions="End"
HorizontalOptions="End"
Margin="10" />
</Grid>
This should work for you.

ListView taking more height than needed and Entry being hidden

I am working on a Xamarin.Forms PCL project.
I am working on a page that displays a post, the comments for that post, and an Entry to write a comment.
My XAML is
<ContentPage.Content>
<StackLayout>
<ScrollView>
<StackLayout>
<StackLayout>
<local:PostListView x:Name="Post" ItemTemplate=...>
</local:PostListView>
</StackLayout>
<StackLayout>
<Label x:Name="CommentHeader" FontSize="15" FontAttributes="Bold" HorizontalOptions="CenterAndExpand"/>
<ListView x:Name="CommentsList" HasUnevenRows="True" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<local:PostViewCell>
...
</local:PostViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</StackLayout>
</ScrollView>
<StackLayout>
<StackLayout x:Name="CommentBox" Padding="10, 5, 10, 10">
<Entry x:Name="CommentEntry" Placeholder="Comment" BackgroundColor="GhostWhite" Focused="CommentEntry_Focused" Unfocused="CommentEntry_Unfocused" TextChanged="CommentEntry_TextChanged"/>
</StackLayout>
</StackLayout>
</StackLayout>
</ContentPage.Content>
The first custom ListView displays only a single post at a time but I use to so I can use the ItemTemplate feature.
My problems are:
The whole page should scroll together (leaving the comment entry) but the first ListView covers the whole screen and only shows the comment ListView once you scroll down, it only needs about 1/5 of the page the rest is blank white space.
The comment entry is supposed to sit on the bottom of the page but appear ontop the keyboard when focused but instead gets covered by the keyboard.
For The First point you can try Grid Instead Of Stack Layout to be able control the portion of each Container.
About the second Point I suggest you take a look at
https://github.com/paulpatarinski/Xamarin.Forms.Plugins/tree/master/KeyboardOverlap