Xamarin.Forms. Collectionview adds a lot of extra white space after its content

Viewed 1432

I would like there to be no empty space after the content of the collection view.

I tried to put my button in footer but then i ran into problem that property isenabled = false is not being applied to it in my code behind. Here is my xaml file:

<ContentPage.Content>
    <RefreshView x:DataType="local:QuestionViewModel" Command="{Binding LoadCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
        <ScrollView>
            <StackLayout>
                <views:MyTextView LaTeX="{Binding Formulation}" HorizontalOptions="Center" Margin="15, 10, 15, 0"/>
                <!--<RefreshView x:DataType="local:QuestionViewModel" Command="{Binding LoadCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">-->
                    <CollectionView
                        ItemsSource="{Binding Answers, Mode=TwoWay}"
                        SelectedItems="{Binding SelectedAnswers, Mode=TwoWay}"
                        SelectionMode="Multiple"
                        x:Name="collectionView"
                        SelectionChanged="collectionView_SelectionChanged"
                        >
                        <CollectionView.ItemsLayout>
                            <LinearItemsLayout Orientation="Vertical"/>
                        </CollectionView.ItemsLayout>
                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="model:Answer">
                            <StackLayout Padding="10">
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup Name="CommonStates">
                                        <VisualState Name="Normal">
                                            <VisualState.Setters>
                                                <Setter TargetName="frame" Property="Frame.BackgroundColor" Value="{Binding AnswerColor}"/>
                                            </VisualState.Setters>
                                        </VisualState>
                                        <VisualState Name="Selected">
                                            <VisualState.Setters>
                                                <Setter TargetName="frame" Property="Frame.BackgroundColor" Value="{DynamicResource MainColor}"/>
                                                <Setter TargetName="label" Property="views:MyTextView.TextColor" Value="White"/>
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Frame CornerRadius="10" HasShadow="True" x:Name="frame" BackgroundColor="{Binding AnswerColor}">
                                    <views:MyTextView x:Name="label" LaTeX="{Binding Content}" />
                                </Frame>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
                <!--</RefreshView>-->
                <StackLayout>
                    <Label x:Name="conditionLabel" TextColor="{DynamicResource AnswerColor}"/>
                    <Button x:Name="checkButton" Text="Проверить ответы" CornerRadius="10" Margin="10"
                                Command="{Binding CheckAnswersCommand}"/>
                </StackLayout>
            </StackLayout>
        </ScrollView>
    </RefreshView>
</ContentPage.Content>

Result: 1 part of screen 2 part of screen

2 Answers

You shouldn't use Listview/Collection View with in Scrollview as described in official documentation.

There is an alternative to listview within Scrollview. Look at following code:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ScrollViewDemos"
             x:Class="ScrollViewDemos.Views.ColorListPage"
             Title="ScrollView demo">
    <ScrollView>
        <StackLayout BindableLayout.ItemsSource="{x:Static local:NamedColor.All}">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <StackLayout Orientation="Horizontal">
                        <BoxView Color="{Binding Color}"
                                 HeightRequest="32"
                                 WidthRequest="32"
                                 VerticalOptions="Center" />
                        <Label Text="{Binding FriendlyName}"
                               FontSize="24"
                               VerticalOptions="Center" />
                    </StackLayout>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </ScrollView>
</ContentPage>

Follow Documentation for more support: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/scrollview

Unfortunately, this is a known problem, and an open issue.

See that thread for possible work-arounds. And to track any progress on fixing it.

Bottom line: you have to manually specify/calculate height. There are multiple ways to do so, of various difficulty. Thread mentions some. You would need to Google for more details.

One quick-and-dirty solution I like, when acceptable, is to wrap CollectionView in Grid, and then use RowDefinitions to force how much height is given to row containing CollectionView, how much to everything else. Something like:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*" />
        <RowDefinition Height="2*" />
    </Grid.RowDefinitions>

    <CollectionView Grid.Row="0" ...>
        ...
    </CollectionView>

    <StackLayout Grid.Row = "1" ...>
        ... everything that is below the CV ...
    </StackLayout>
 </Grid>

This would restrict row 0 (which contains CollectionView) to top 1/3 of screen.

Related