Andy
Andy

Reputation: 8562

Grid content is clipped only in ScrollView

I have the following XAML and code behind. For some reason, the grid contained within the ScrollView is clipped (the third row is not displayed). I would have expected that everything fits on one screen since the ListView scrolls vertically and could be compacted a bit more.

If I remove the ScrollView and the grid is inline with the other elements, everything displays as expected.

Why is the third row being clipped, and how can I get it to always display?

I'm using Xamarin.Forms 2.5.0 but can also reproduce this with latest 3.1.0, and this is seen in UWP, Android and iOS.

XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:XamarinScrollView"
    x:Name="TheMainPage"            
    x:Class="XamarinScrollView.MainPage">

    <StackLayout BindingContext="{x:Reference TheMainPage}">
        <ActivityIndicator IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}" />
        <Label Text="{Binding StringValue}" LineBreakMode="WordWrap" />
        <Label Text="{Binding StringValue}" />
        <Label Text="{Binding StringValue}" LineBreakMode="WordWrap" />
        <Label Text="{Binding StringValue, StringFormat='String Value: {0}'}" IsVisible="{Binding HasStringValue}" />
        <Label Text="{Binding StringValue, StringFormat='String Value: {0}'}" />
        <Label Text="{Binding StringValue, StringFormat='String Value: {0}'}" />
        <BoxView HeightRequest="2">
            <BoxView.Color>
                <OnPlatform x:TypeArguments="Color">
                    <On Platform="Android">White</On>
                    <On Platform="iOS">Black</On>
                    <On Platform="UWP">Black</On>
                </OnPlatform>
            </BoxView.Color>
        </BoxView>
        <ScrollView Orientation="Horizontal">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Grid.Column="0" Text="{Binding DateValue, StringFormat='Date Value: {0:g}'}" />
                <Label Grid.Row="1" Grid.Column="0" Text="{Binding DateValue, StringFormat='Date Value: {0:g}'}" />
                <Label Grid.Row="2" Grid.Column="0" Text="{Binding StringValue, StringFormat='String Value: {0}'}" />

                <Label Grid.Row="0" Grid.Column="1" Text="{Binding DateValue, StringFormat='Date Value: {0:g}'}" />
                <Label Grid.Row="1" Grid.Column="1" Text="{Binding DateValue, StringFormat='Date Value: {0:g}'}" />
                <Label Grid.Row="2" Grid.Column="1" Text="{Binding DateValue, StringFormat='Date Value: {0:g}'}" />
            </Grid>
        </ScrollView>
        <Frame Margin="2">
            <Frame.BorderColor>
                <OnPlatform x:TypeArguments="Color">
                    <On Platform="Android">White</On>
                    <On Platform="iOS">Black</On>
                    <On Platform="UWP">Black</On>
                </OnPlatform>
            </Frame.BorderColor>

            <StackLayout Padding="0,0,0,20">
                <Label Text="String Value" />
                <Label Text="{Binding StringValue}" LineBreakMode="WordWrap" />
            </StackLayout>
        </Frame>
        <Frame Margin="2">
            <Frame.BorderColor>
                <OnPlatform x:TypeArguments="Color">
                    <On Platform="Android">White</On>
                    <On Platform="iOS">Black</On>
                    <On Platform="UWP">Black</On>
                </OnPlatform>
            </Frame.BorderColor>

            <ListView ItemsSource="{Binding ListItems}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Margin="0,0,0,10">
                                <Label Text="{Binding StringValue1}" />
                                <Label Text="{Binding StringValue2}" />
                                <Label Text="{Binding StringValue3}" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Frame>
    </StackLayout>
</ContentPage>

Code behind

using System;
using System.Collections.Generic;
using Xamarin.Forms;

namespace XamarinScrollView {
    public partial class MainPage : ContentPage {
        public MainPage() {
            InitializeComponent();
        }

        public string StringValue => "This is a string";

        public DateTime DateValue => DateTime.Now;

        public bool HasStringValue => true;

        private readonly List<ListItem> listItems = new List<ListItem> { 
            new ListItem(),
        };
        public IEnumerable<ListItem> ListItems => listItems;
    }

    public sealed class ListItem { 
        public string StringValue1 => "1. This is a string";
        public string StringValue2 => "2. This is a string";
        public string StringValue3 => "3. This is a string";
    }
}

Upvotes: 0

Views: 899

Answers (3)

Andy
Andy

Reputation: 8562

Setting MinimumHeightRequest on both the ScrollView and the contained GridView seems to resolve this for me.

Upvotes: 1

Bruno Caceiro
Bruno Caceiro

Reputation: 7189

You have a ScrollView, however, you do not wan't for elements to be clipped. Your solution is to give a HeightRequest to the ScrollView.

Upvotes: 1

TaylorD
TaylorD

Reputation: 687

Depending on the number of items in the ListView, the ScrollView will shrink so the ListView has enough space to show its items.

Even though your grid has Auto rows and will create rows to fit the content being shown, the ScrollView will shrink to a certain point. The Grid still has the amount of space needed for its contents, but the ScrollView is only showing what it can for the space the ScrollView is given in the StackLayout. Since you are only allowing Horizontal orientation for your ScrollView, that is why you aren't able to scroll to see the last row of your Grid.

Upvotes: 0

Related Questions