1
votes

I have a StackLayout that contains Grid and this Grid again contains a Grid and the second Grid contains ScrollView. The problem is that the ScrollView is not scrolling when the top most layout is StackLayout, if I change it in Grid or RelativeLayout, it scrolls.

Here is Xaml code:

<StackLayout>
    <Label Text="Home Page" HorizontalOptions="Center" FontSize="Large"/>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Grid Grid.Row="0">
            <Grid.Style>
                <OnIdiom x:TypeArguments="Style"
                         Desktop="{StaticResource TabletGridStyle}"
                         Phone="{StaticResource PhoneGridStyle}" />
            </Grid.Style>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

            <StackLayout Grid.Row="0" Orientation="Horizontal">
                <Label x:Name="cityName" Text="City" FontSize="Large"
                            VerticalOptions="Center"
                            HorizontalOptions="StartAndExpand" />

                <SearchBar x:Name="SearchBar"
                                HorizontalOptions="EndAndExpand"
                                VerticalOptions="Center"
                                WidthRequest="250"
                                Placeholder="Search..."
                                TextChanged="Handle_SearchTextChangedSearch" />
            </StackLayout>

            <ScrollView Grid.Row="1" Orientation="Vertical" VerticalScrollBarVisibility="Always">
                <StackLayout VerticalOptions="FillAndExpand">
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                    <Label Text="Sample Text" />
                </StackLayout>
            </ScrollView>

            <ListView x:Name="ListView"
                      ItemsSource="{Binding Places}"
                      ItemSelected="ItemSelected"                          
                      HasUnevenRows="True"
                      Grid.Row="1"
                      IsVisible="False"
                      BackgroundColor="#FFEBFF"
                      HeightRequest="100"
                      WidthRequest="250"
                      HorizontalOptions="End"
                      RowHeight="40"
                      Opacity="0.9">

                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Padding="10">
                                <Label VerticalOptions="Center"
                                               TextColor="Black">
                                    <Label.FormattedText>
                                        <FormattedString>
                                            <Span Text="{Binding name}" />
                                            <Span Text=", " />
                                            <Span Text="{Binding country}" />
                                        </FormattedString>
                                    </Label.FormattedText>
                                </Label>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
        <Frame Grid.Row="0" x:Name="loadingFrame" IsVisible="False" VerticalOptions="Center" HasShadow="True" CornerRadius="5">
            <StackLayout Orientation="Horizontal">
                <ActivityIndicator x:Name="activityIndicatorPhone" Margin="10, 0, 0, 0" IsRunning="False" />
                <Label Text="Loading..." VerticalOptions="Center" FontSize="Large" Margin="20, 0, 0, 0">
                    <Label.IsVisible>
                        <OnIdiom x:TypeArguments="x:Boolean">
                            <OnIdiom.Phone>true</OnIdiom.Phone>
                            <OnIdiom.Desktop>false</OnIdiom.Desktop>
                        </OnIdiom>
                    </Label.IsVisible>
                </Label>
            </StackLayout>
        </Frame>
    </Grid>
</StackLayout>

Here is the Output I am getting

enter image description here

When I change the parent StackLayout to Grid, the content is scrolling.

Here's is the modified code:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Label Grid.Row="0" Text="Home Page"  HorizontalOptions="Center" FontSize="Large" />
    <Grid Grid.Row="1">
    ..........
    ..........

Scrollable output:

enter image description here

But how can I achieve this when top most Layout is StackLayout?

2

2 Answers

0
votes

You have both ScrollView and ListView assigned to Grid.Row="1". Hope it helps.

0
votes

You can put the ListView inside a ScrollView .As follow:

<StackLayout>
    <!-- Place new controls here -->
    <Label Text="Welcome to Xamarin.Forms!" 
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
    <ScrollView>
        <StackLayout>
            <Label Text="Hello!!! Welcome to Smiley Panda"></Label>
            <Label Text="Hello!!! Smiley Panda Loves you"></Label>
            <Label Text="Hello!!! Welcome to Smiley Panda"></Label>
            <Label Text="Hello!!! Smiley Panda Loves you"></Label>
            <Label Text="Hello!!! Welcome to Smiley Panda"></Label>
            <Label Text="Hello!!! Smiley Panda Loves you"></Label>
            <app20:CustomListView x:Name="listview"
                                  MinimumHeightRequest="96"
                                  Margin="16,0" />
        </StackLayout>
    </ScrollView>
</StackLayout>

Here you can see that I custom a ListView to implement it . If in UWP , you can ignore it ,just use the normal ListView .

public class CustomListView : ListView
{
    public static readonly BindableProperty IsNestedScrollProperty = BindableProperty.Create(
       propertyName: "IsNestedScroll",
       returnType: typeof(bool),
       declaringType: typeof(CustomListView),
       defaultValue: false
       );

    public bool IsNestedScroll
    {
        get
        {
            return (bool)GetValue(IsNestedScrollProperty);
        }
        set
        {
            SetValue(IsNestedScrollProperty, value);
        }
    }
}

In ContentPage , add sample data for ListView :

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        listview.ItemsSource = AddPandaFamily();
    }

    List<string> pandaFamily = new List<string>();
    public List<string> AddPandaFamily()
    {
        for (int i = 0; i < 50; i++)
        {
            pandaFamily.Add("Smiley Panda");
            pandaFamily.Add("Red Panda");
            pandaFamily.Add("Qinling Panda");
            pandaFamily.Add("Oleosa Panda");
            pandaFamily.Add("Ailuropoda Panda");

        }
        return pandaFamily;
    }
}

The effect in UWP :

enter image description here

If need to implement it in Android , you need to use the BindableProperty in CustomRenderer in Xamarin Android .

public class CustomListViewRenderer : ListViewRenderer
{
    public CustomListViewRenderer(Android.Content.Context context) : base(context)
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            var listview = this.Control as Android.Widget.ListView;
            listview.NestedScrollingEnabled = true;
        }
    }
}