Xamarin Forms CollectionView Last item not showing properly - user-interface

I have a simple horizontal CollectionView which works fine except that the last item is not showing properly and i have to force scroll it to see it.
I tried all kinds of padding and margins but the only property that will make it show is if make ItemSpacing="20" or bigger. The problem is that, if i added more items, the issue still will show again and this is a dynamic list.
this is the code for the stacklayout under the content page directly.
<StackLayout VerticalOptions="Center" HorizontalOptions="FillAndExpand">
<StackLayout BackgroundColor="LightGray" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" >
<CollectionView HeightRequest="40" VerticalOptions="Fill" HorizontalOptions="Fill" Margin="5" >
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" ItemSpacing="10"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Open (Item)</x:String>
<x:String>Side Menu</x:String>
<x:String>How to?</x:String>
<x:String>Back/Cancel</x:String>
<x:String>Logout</x:String>
<x:String>Yes/No</x:String>
<x:String>App Info</x:String>
</x:Array>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame BackgroundColor="White" BorderColor="DarkCyan" CornerRadius="20" HasShadow="False" Padding="10" Margin="0">
<Label Text="{Binding}" TextColor="DarkCyan"/>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</StackLayout>

Related

Xamarin.Forms.CollectionView shows different size then what I set when ItemsLayout is GridItemsLayout

Only items in first row shows different size then other items. However I set same size to all items in XAML. It only happens on Android.
<CollectionView
HorizontalOptions="FillAndExpand"
HeightRequest="100"
ItemsSource="{Binding Items}"
SelectionMode="Single">
<CollectionView.ItemsLayout>
<GridItemsLayout
Orientation="Vertical"
Span="4"
HorizontalItemSpacing="10"
VerticalItemSpacing="10"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Image
WidthRequest="50"
HeightRequest="50"
Source="{local:ImageResource CollectionView.Image.png}"/>
<Label
Text="{Binding Title}"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Github
I download your sample to test, I can not run your sample, I create new project and upload one sample, you can take a look:
https://github.com/CherryBu/collectionsample1
This is the screenshot:

CollectionView disabling scrolling in Xamarin forms

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>
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/
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! 🙂

How to make Scrollable Label in List Xamarin Forms

I have a List view with fixed Row Height. Inside List view there is Label with large description. I am trying to make this label scroll able. Can anyone help please.
<ListView ItemsSource="{Binding ServiceList, Mode=TwoWay}" RowHeight="100">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:ServiceModel">
<ViewCell>
<ScrollView
Margin="0"
Padding="0"
HeightRequest="50">
<Label
LineBreakMode="WordWrap"
Style="{StaticResource blackColorLabel}"
Text="{Binding ServiceDescription}" />
</ScrollView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
As mentioned in the comments, you shouldn't nest scrollviews because the behavior is erratic. You can use BindableLayout though.
<StackLayout BindableLayout.ItemsSource="{Binding ServiceList}">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:ServiceModel">
<ScrollView
Margin="0"
Padding="0"
HeightRequest="50">
<Label
LineBreakMode="WordWrap"
Style="{StaticResource blackColorLabel}"
Text="{Binding ServiceDescription}" />
</ScrollView>
</DataTemplate>
</BindableLayout.ItemTemplate>
RowHeight is not a thing for BindableLayouts, but you could probably wrap your Label in a ContentView and set the HeightReqeust of the ContentView to 100. Or maybe even just set your Label Height Request to 100 and see what that does.

How to change backgroundcolor of GroupDisplayBinding in Xamarin Forms?

I am trying to change the background color of GroupDisplayBinding only that is inside the list view without affecting the list. As you can see in the image, the background is lightgray, also I want to change the margin of it too if that's possible.
<ListView
IsVisible="{Binding ShowList}"
IsGroupingEnabled="True"
HasUnevenRows="True"
SelectionMode="None"
SeparatorVisibility="None"
BackgroundColor="#ffffff"
GroupDisplayBinding="{Binding GroupName}"
GroupShortNameBinding="{Binding ShortName}"
ItemsSource="{Binding List}">
<ListView.Behaviors>
<behaviors:EventToCommandBehavior Command="{Binding ListItemTappedCommand}"
EventName="ItemTapped" />
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame HasShadow="False"
CornerRadius="0"
Margin="2"
Padding="10"
BackgroundColor="#ffffff"
BorderColor="#000000">
<StackLayout Orientation="Horizontal"
Spacing="0"
Padding="0"
Margin="0">
<Label Text="{Binding Name}"
HorizontalOptions="StartAndExpand"
Style="{StaticResource ListTextStyle}"
TextColor="#2278B5"/>
<Label Text=">"
Style="{StaticResource ListTextStyle}"
TextColor="#2278B5"
HorizontalOptions="End"
FontSize="24" />
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
We could take it one step further and implement our own custom header cell with a nice background color.
The demo is very simple and just contains a Label, which binds to GroupName and I am placing it inside of a StackLayout with a bit of custom padding and a background color.
<ListView IsVisible="{Binding ShowList}"
IsGroupingEnabled="True"
HasUnevenRows="True"
SelectionMode="None"
SeparatorVisibility="None"
BackgroundColor="#ffffff"
GroupDisplayBinding="{Binding GroupName}"
GroupShortNameBinding="{Binding ShortName}"
ItemsSource="{Binding List}">
// set the appearance of Header here as you want
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell Height="25">
<StackLayout VerticalOptions="FillAndExpand" Padding="5" BackgroundColor="#3498DB">
<Label Text="{Binding GroupName}" TextColor="White" Margin="10" VerticalOptions="Center"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
//...
</ListView.ItemTemplate>
</ListView>

Transparency not rendering the same on xamarin.ios project

I just can't understand why the background for my side menu on xamarin forms won't render the same on my xamarin.ios. Yet in other parts of the project my list views render and look the same when I use transparent backgrounds, I even tried copying and pasting the xaml code from other parts of the project where it does render the same, but still it does not work. In case anyone's wondering the side menu on ios was requested by the client.
Attached below I have 2 images showing how the side menu renders differently on the 2 platforms
Here's the Xaml code I'm using for my Side Menu:
<MasterDetailPage.Master>
<StackLayout Orientation="Vertical" BackgroundColor="Transparent" Spacing="0">
<StackLayout
HorizontalOptions="Fill"
Orientation="Horizontal"
VerticalOptions="Fill" BackgroundColor="Black" Padding="50, 50, 50, 50">
<StackLayout HorizontalOptions="Center" Orientation="Vertical">
<ffimageloading:CachedImage x:Name="ProfilePictureCircleImage"
LoadingPlaceholder="profile_image_placeholder.png"
ErrorPlaceholder="profile_image_placeholder.png"
DownsampleToViewSize="true"
FadeAnimationEnabled="true"
HeightRequest="65"
WidthRequest="65">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation/>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
</StackLayout>
<StackLayout
HorizontalOptions="CenterAndExpand"
Orientation="Vertical"
VerticalOptions="CenterAndExpand">
<Label
x:Name="FullNameLabel"
FontSize="18"
HorizontalOptions="Center"
TextColor="White"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</StackLayout>
<BoxView HeightRequest="2" BackgroundColor="#D90B31"/>
<ListView
x:Name="NavigationMenuItems"
ItemSelected="OnMenuItemSelected"
BackgroundColor="{StaticResource TileColour}"
RowHeight="60"
SeparatorVisibility="None"
SeparatorColor="Transparent">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!-- Main design for menu items -->
<StackLayout
Padding="20,10,0,10"
Orientation="Horizontal"
Spacing="20"
VerticalOptions="FillAndExpand"
BackgroundColor="Transparent">
<local:TintedCachedImage TintColor="{StaticResource SideMenuIconColor}"
Source="{Binding Icon}"
VerticalOptions="Center"
DownsampleToViewSize="true"
HeightRequest="19"
WidthRequest="19"/>
<Label
FontSize="15"
Text="{Binding Title}"
TextColor="{StaticResource SideMenuTextColor}"
VerticalOptions="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage />
</MasterDetailPage.Detail>
above are pictures illustrating how it looks across the 2 platforms.
Found the solution to this question on another stackoverflow thread I had to use a custom renderer:
public class CustomSideMenuRenderer: TabletMasterDetailRenderer
{
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
var master = ViewControllers[0];
master.View.BackgroundColor = UIColor.Clear;
var detail = ViewController.ChildViewControllers[1];
}
}

Resources