Not able to see ListView inside ScrollView

gffggffg USMember
edited May 2015 in Xamarin.Forms

Hi,

I have a ListView inside a ScrollView, but I cant see the ListView or the ScrollView.
This is my Code:

`<?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:pages="clr-namespace:AdWordsApp.Pages;assembly=App"
">

<StackLayout>

    <StackLayout Orientation="Horizontal">
        <Button Text="Start" HorizontalOptions="StartAndExpand" Clicked="Button_OnClicked_Start" />
        <Button Text="End" HorizontalOptions="CenterAndExpand" Clicked="Button_OnClicked_End" />
    </StackLayout>

    <Label Text="Title" FontSize="Large" HorizontalOptions="Center" VerticalOptions="Center"
           HeightRequest="50" />

    <ScrollView Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">

        <StackLayout Orientation="Horizontal">
            <Picker Scale="0.8" HorizontalOptions="StartAndExpand" WidthRequest="150"
                    SelectedIndex="{Binding Compare}"
                    SelectedIndexChanged="Picker_OnSelectedIndexChanged_Compare">
                <Picker.Items>
                    <x:String>1</x:String>
                    <x:String>2</x:String>
                    <x:String>3</x:String>
                    <x:String>4</x:String>
                    <x:String>5</x:String>
                </Picker.Items>
            </Picker>
            <Label Text="compare" HorizontalOptions="Center" VerticalOptions="Center" FontSize="Small" />
        </StackLayout>

        <pages:OxyView />

        <StackLayout Orientation="Horizontal">
            <Grid Padding="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="20" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="120" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="60" />
                    <ColumnDefinition Width="80" />
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Grid.Column="0" Text="Status" VerticalOptions="Start"
                       HorizontalOptions="Center" FontSize="Small" TextColor="White" LineBreakMode="NoWrap" />

                <Label Grid.Row="0" Grid.Column="1" Text="One" VerticalOptions="End" HorizontalOptions="Start"
                       FontSize="Small" TextColor="White" LineBreakMode="NoWrap" />

                <Label Grid.Row="0" Grid.Column="2" Text="two" VerticalOptions="Center"
                       HorizontalOptions="Start" FontSize="Small" TextColor="White" LineBreakMode="NoWrap" />

                <Label Grid.Row="0" Grid.Column="3" Text="three" VerticalOptions="End"
                       HorizontalOptions="Start" FontSize="Small" TextColor="White" />

            </Grid>

        </StackLayout>

        <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <ListView x:Name="list"
                      ItemsSource="{Binding Titles}"
                      ItemTapped="OnItemSelected"
                      IsGroupingEnabled="True"
                      GroupDisplayBinding="{Binding Key}"
                      GroupShortNameBinding="{Binding Key}"
                      HasUnevenRows="True"
                      HeightRequest="600"

                      Footer="Gesamt: ">
                <ListView.GroupHeaderTemplate>
                    <DataTemplate>

                    </DataTemplate>
                </ListView.GroupHeaderTemplate>

                <ListView.ItemTemplate>
                    <DataTemplate>

                    </DataTemplate>
                </ListView.ItemTemplate>

            </ListView>
        </StackLayout>

        <StackLayout Orientation="Horizontal">
            <Grid Padding="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="20" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="120" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="60" />
                    <ColumnDefinition Width="80" />
                </Grid.ColumnDefinitions>
                <Label Grid.Row="0" Grid.Column="0" Text="Total: " VerticalOptions="Center"
                       HorizontalOptions="Center" FontSize="Small" TextColor="White" LineBreakMode="NoWrap" />
            </Grid>
        </StackLayout>

    </ScrollView>
</StackLayout>

`

Im can see everything above the ScrollView.
But inside the ScrollView I can only see Label inside the Grid.

Why I cant see the ListView?

Thanks in advance,

Michael

Best Answer

Answers

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    You shouldn't put a ListView inside a ScrollView for several reasons. The most obvious reason is that ListViews all scroll. Aside from that, the problem here is that ListViews want to fill their container, but ScrollViews want to fit their content area to their children. If the ScrollView asks a ListView how big it should be it will respond with "as small as you want me to be", which means zero size. So that's what you get.

  • gffggffg USMember

    Yeah, this works for me with one StackLayout.

    Now I can see it like expected.

    The only issue is, that I cant scroll inside the ListView.

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    Again, see my comment. A ListView should not be embedded in a ScrollView, regardless of whether you have a StackPanel in between. It's just not a good idea.

    What are you trying to do? Can you show us a mockup of the desired layout?

  • AndrewMobileAndrewMobile ✭✭✭✭ USMember ✭✭✭✭
    edited May 2015

    @gffg
    I second that, don't put a ListView inside ScrollView. Bad idea.
    What you want to do I think is instead use a Grid for example where all GridRows have Auto property set and just one GridRow has it * (Star) such that the ListView will stretch across height
    Something like

    <Grid>
     <Grid.RowDefinitions Height="Auto">
     <Grid.RowDefinitions>
     <Grid.RowDefinitions Height="Auto">
    
    <StackLayout>
    ... 
    </StackLayout>
    
    <ListView Grid.Row="1">
    ..
    </ListView>
    
    <StackLayout Grid.Row="2">
    ... 
    </StackLayout>
    
    <Grid>
    
  • gffggffg USMember

    Is it possible to show the whole contrent of ListView directly?
    Then I dont need it to be scrollable because the ScrollView is doing this for me.

    Thank you

  • AndrewMobileAndrewMobile ✭✭✭✭ USMember ✭✭✭✭

    @gffg look to the XAML sample I just posted above

  • adamkempadamkemp mod USInsider, Developer Group Leader mod
    edited May 2015

    Another approach is to make the stuff above the ListView be a header using the Header and/or HeaderTemplate properties.

  • gffggffg USMember

    Hi,

    This is like the page should look like:

    Button Button Picker
    Title
    Picker Label Picker }
    OxyPlot } } } scrollable
    Label Label Label } }
    ListView } scrollable }
    Label Label Label

    The first two rows and the last row should be alwas there.
    The rows betwenn woul be nice if they where scrollable because there is not enough Space to show everything.

    If I do it with grids like AndreiNitescu said but it makes no difference to the solution without grid.

    Is there a way to minimize for example the Plot on Click?
    Or is there a way to let the ListView always show everything? So it dont need to be scrallable.

    Or is it possible to put the plot and the row over it with the Pickers and the Label into a StackLayout and this StackLayout into the List Header? Is yes how does it work?

    Thanks you

  • gffggffg USMember
    edited May 2015

    I tried to put it into the Header like this:

    <ListView.Header> <StackLayout Orientation="Vertical"> <StackLayout Orientation="Horizontal"> <Picker.... /> <Label ...../> <Picker...../> </StackLayout> <pages:OxyView /> </StackLayout> </ListView.Header>

    But then it just show the horizontal StackLayout with its content but not the OxyPlot.

  • gffggffg USMember

    Ok,

    I found a nice solution.

    When the Page appears Im showing the Plot with another Button among the Plot.
    With that Button Im changing the visibility of the Plot.

    This is the best way for me to make enough Space for the User to see everything :)

    Thanks alot for the help of all of you

  • Adit2705Adit2705 INMember

    Here is my Code I am not able to use listview inside Scrollview

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    @adamkemp said:
    Again, see my comment. A ListView should not be embedded in a ScrollView, regardless of whether you have a StackPanel in between. It's just not a good idea.

  • dwndwn ATMember

    @adamkemp I get the problems that a listview inside a scrollview causes.
    Do you have a suggestion how to create a Xamarin Forms View containing

    • Image (fixed size, e.g. half height of screen)
    • Dynamic list of comments (expanded i.e. so no scrolling in the list, HasUnevenRows="true")
    • Map (fixed size, e.g. half height of screen)

    The key problem is that the content does not fit on the screen, it makes scrolling inevitable
    I can get that to work with fixed sized rows (HasUnevenRows="false",RowHeight="123"), by putting everything in a scrollview
    Dynamic row height does not work, but I don't know what the correct approach to that would be

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    @dwn: It's not clear to me what your UI looks like or how it should behave. I am guessing that what you want is to have the image followed by N comments followed by the map, and then have all of that scroll together. Is that right?

    In that case there are a few approaches you might take:

    1. Put everything in a single ListView using a header and footer. Put the image in a header and the map in a footer and then have the comments be normal rows.
    2. Put everything in a single ListView with rows for the image and map. The first row would be the image, then N comment rows, then a map row. You can use a data template selector for this. I think there have probably been some significant advancements in the data template selector approach since I last worked with Xamarin.Forms so I think you should google a bit for this.
    3. Don't use a ListView at all. Instead, put everything in a StackLayout (either one StackLayout with 2 + N views: an image view, N comments, then a map view; or a StackLayout with 3 views: an image view, another nested StackLayout with N comments, and then a map view). Embed that StackLayout in a ScrollView.

    In each of those approaches the solution is basically the same as my original advice: don't nest a ListView inside a ScrollView. Use one or the other, but not both at the same time.

  • dwndwn ATMember

    @adamkemp Thanks for your thorough explanation!
    You guessed correctly regarding the layout and behavior.

    I will try (1) and if it doesn't work fall back to (3).

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    I forgot to mention, approach 3 is suitable if the number of comments is expected to be small. At some point the cost of creating the views for the comments becomes great enough that the virtualization you get from the ListView is worth it even if it's a bit harder to set up. How many comments you need to cross that threshold depends on the app (i.e., how expensive is it to create each comment view).

  • dwndwn ATMember

    Thanks for the hint @adamkemp !

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    No problem! Did you get it working? Which solution did you go with?

  • dwndwn ATMember

    @adamkemp sorry for the late answer but I was off some time

    unfortunately I did not get it working yet
    The Header approach looked fine, but DataBinding is not working
    So in this case I went for HeaderTemplate, but in this case I am not able to access named views anymore

    I need to access them, e.g. the map to add pins; is there a way around this dilemma?

    see

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    I don't know what you mean.

  • dwndwn ATMember
    edited November 2016

    @adamkemp consider

    <ListView.HeaderTemplate > <DataTemplate> <StackLayout Orientation="Horizontal" Padding="10,5,5,10" BackgroundColor="Yellow"> <Label Text="~~"/> <Label x:Name="myLabel" Text="{Binding .}"/> <Label Text="~~"/> </StackLayout> </DataTemplate> </ListView.HeaderTemplate>

    When the header is defined as DataTemplate I cannot access myLabel in the code.
    But if it is defined as Header then Binding will not work.

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    If you're using a data template you should use bindings for everything. Whatever you were using the name for before you need to convert to use bindings instead.

    If you're using just the Header then the bindings are relative to the same object that has the ItemsSource binding.

Sign In or Register to comment.