Xamarin Scrollview only showing partial data up to screen end, and then blank when scrolling

DanRob 1 Reputation point
2021-03-15T12:06:41.02+00:00

Hello,

I have a frame with a stacklayout inside of a scrollview, when I open the page, labels and data show up, but only up to the bottom screen edge, everything after that gets cut (is simply blank). Tapping on a entry field makes the rest of the data and labels show up, but obviously that is undesirable behavior. I have tried changing the VerticalOptions and Grid definitions to multiple combinations, but nothing works.
Any ideas or suggestions as to how to solve this would be greatly appreciated.

Screenshot:

77760-screenshot-account-data-scrollview-bug.png

XAML:

 <ContentPage.Content>  
        <ScrollView Orientation="Vertical">  
            <!-- only show the main content when loading is finished -->  
            <Grid Padding="10">  
  
                <!-- this frame is only visible when the page is loading its main data -->  
                <Frame  
                    BackgroundColor="{AppThemeBinding White, Light={StaticResource Light_FrameBackground}, Dark={StaticResource Dark_FrameBackground}}"  
                    CornerRadius="10"  
                    Grid.Row="0"  HorizontalOptions="FillAndExpand" HasShadow="False"  
                    IsVisible="{Binding LoadingFinished, Converter={StaticResource boolInvert}}">  
                    <StackLayout Orientation="Vertical" VerticalOptions="FillAndExpand">  
                        <ActivityIndicator  
                            Color="{AppThemeBinding Black, Light={StaticResource Light_TextOnFrame}, Dark={StaticResource Dark_TextOnFrame}}"  
                            IsRunning="{Binding LoadingFinished, Converter={StaticResource boolInvert}}"  
                            HorizontalOptions="Center" VerticalOptions="Center" />  
                        <Label x:Name="loadingLabel" FontSize="Large"   
                               Text="{x:Static resources:AppResources.InitLoadData}"  
                               TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnFrame}, Dark={StaticResource Dark_TextOnFrame}}"  
                               HorizontalTextAlignment="Center" HorizontalOptions="Center" VerticalOptions="Center" />  
                    </StackLayout>  
                </Frame>  
  
                <!-- the cool main frame, visible after the page finished loading its data -->  
                <Frame  
                    BackgroundColor="{AppThemeBinding White, Light={StaticResource Light_FrameBackground}, Dark={StaticResource Dark_FrameBackground}}"  
                    CornerRadius="22" Grid.Row="0" HasShadow="False" IsVisible="{Binding LoadingFinished}" >  
                    <Grid>  
                        <Grid.RowDefinitions>  
                            <RowDefinition Height="Auto" />  
                            <RowDefinition Height="Auto" />  
                        </Grid.RowDefinitions>  
                        <Grid.ColumnDefinitions>  
                            <ColumnDefinition Width="*" />  
                        </Grid.ColumnDefinitions>  
  
                        <StackLayout x:Name="mainFieldList" Grid.Row="0" Margin="0,5,0,5" Orientation="Vertical"  HorizontalOptions="FillAndExpand">  
                            <!-- the properties that come here are set in code -->  
                            <Label Text="{x:Static resources:AppResources.SettingsPageEmailLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="EmailEntry" Text="{Binding UserMail}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding UserMailEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                            <Label Text="{x:Static resources:AppResources.SettingsPageMobileNumberLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="MobileEntry" Text="{Binding Mobile}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding MobileEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                            <Label Text="{x:Static resources:AppResources.AccountDataPageAddressLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="AddressEntry" Text="{Binding Address}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding AddressEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                            <Label Text="{x:Static resources:AppResources.AccountDataPageFirstnameLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="FirstnameEntry" Text="{Binding Firstname}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding FirstnameEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                            <Label Text="{x:Static resources:AppResources.AccountDataPageLastnameLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="LastnameEntry" Text="{Binding Lastname}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding LastnameEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                            <Label Text="{x:Static resources:AppResources.AccountDataPageCountryLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="CountryEntry" Text="{Binding Country}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding CountryEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                            <Label Text="{x:Static resources:AppResources.AccountDataPageCityLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="CityEntry" Text="{Binding City}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding CityEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                            <Label Text="{x:Static resources:AppResources.AccountDataPageZippostalcodeLabelText}"   
                                   TextColor="{AppThemeBinding Gray, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}"  
                                   FontSize="Medium" Margin="0,20,0,0" />  
                            <Entry x:Name="ZipEntry" Text="{Binding Zippostalcode}" Keyboard="Email" BackgroundColor="Transparent" IsEnabled="{Binding ZippostalcodeEnabled}"  
                                   TextColor="{AppThemeBinding Black, Light={StaticResource Light_TextOnAppBackground}, Dark={StaticResource Dark_TextOnAppBackground}}" />  
                        </StackLayout>  
  
                        <!-- save button and activity indicator -->  
                        <Button x:Name="saveButton" Grid.Row="1" Clicked="OnSaveButtonClicked" IsVisible="True"  
                                Text="{x:Static resources:AppResources.SaveButtonText}" BorderRadius="22"  
                                BackgroundColor="{AppThemeBinding {StaticResource CommonGreen}, Light={StaticResource Light_GreenButtonAlternative}, Dark={StaticResource Dark_GreenButtonAlternative}}"  
                                TextColor="{AppThemeBinding White, Light={StaticResource Light_TextOnButton}, Dark={StaticResource Dark_TextOnButton}}"  
                                VerticalOptions="Center" FontSize="Small" />  
                        <ActivityIndicator x:Name="activityIndicator" Grid.Row="1" IsVisible="false" IsRunning="false"  
                                           HorizontalOptions="Center" />  
                    </Grid>  
                </Frame>  
            </Grid>  
        </ScrollView>  
    </ContentPage.Content>  
Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,325 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Fadi H Rezq 11 Reputation points
    2021-03-22T18:25:36.84+00:00

    This might be related to this open Xamarin bug which was introduced in Xamarin 5: https://github.com/xamarin/Xamarin.Forms/issues/13597

    The workaround mentioned that the ScrollView should be encapsulated in a ContenView. That seemed to work for me.

    Hope it helps and hope more that this bug is fixed!

    1 person found this answer helpful.

  2. DanRob 1 Reputation point
    2021-03-16T11:13:14.34+00:00

    @Leon Lu (Shanghai Wicresoft Co,.Ltd.)
    Thank you for your response and trying it out. That's a bit frustrating that it works for you, since that makes the problem somewhat more difficult to pin-point, since I don't think the code-behind has something to do with it. Here is my viewmodel, I'll try to make a demo and upload it later.

    ViewModel:

    public class AccountViewModel : INotifyPropertyChanged {

        public AccountViewModel() {  
    
        }  
    
        public event PropertyChangedEventHandler PropertyChanged;  
        protected virtual void OnPropertyChanged(string propertyName) {  
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
        }  
    
        #region Values  
        private String userMail = "";  
        public String UserMail {  
            get {  
                return this.userMail;  
            }  
            set {  
                if (value != null && !userMail.Equals(value)) {  
                    this.userMail = value;  
                    OnPropertyChanged("UserMail");  
                }  
            }  
        }  
    
        private String mobile = "";  
        public String Mobile {  
            get {  
                return this.mobile;  
            }  
            set {  
                if (value != null && !mobile.Equals(value)) {  
                    this.mobile = value;  
                    OnPropertyChanged("Mobile");  
                }  
            }  
        }  
    
        private String address = "";  
        public String Address  
        {  
            get  
            {  
                return this.address;  
            }  
            set  
            {  
                if (value != null && !address.Equals(value))  
                {  
                    this.address = value;  
                    OnPropertyChanged("Address");  
                }  
            }  
        }  
    
        private String country = "";  
        public String Country  
        {  
            get  
            {  
                return this.country;  
            }  
            set  
            {  
                if (value != null && !country.Equals(value))  
                {  
                    this.country = value;  
                    OnPropertyChanged("Country");  
                }  
            }  
        }  
    
        private String city = "";  
        public String City  
        {  
            get  
            {  
                return this.city;  
            }  
            set  
            {  
                if (value != null && !city.Equals(value))  
                {  
                    this.city = value;  
                    OnPropertyChanged("City");  
                }  
            }  
        }  
    
        private String zippostalcode = "";  
        public String Zippostalcode  
        {  
            get  
            {  
                return this.zippostalcode;  
            }  
            set  
            {  
                if (value != null && !zippostalcode.Equals(value))  
                {  
                    this.zippostalcode = value;  
                    OnPropertyChanged("Zippostalcode");  
                }  
            }  
        }  
    
        private String firstname = "";  
        public String Firstname  
        {  
            get  
            {  
                return this.firstname;  
            }  
            set  
            {  
                if (value != null && !firstname.Equals(value))  
                {  
                    this.firstname = value;  
                    OnPropertyChanged("Firstname");  
                }  
            }  
        }  
    
        private String lastname = "";  
        public String Lastname  
        {  
            get  
            {  
                return this.lastname;  
            }  
            set  
            {  
                if (value != null && !lastname.Equals(value))  
                {  
                    this.lastname = value;  
                    OnPropertyChanged("Lastname");  
                }  
            }  
        }  
        #endregion  
    
        #region Enables  
        private bool userMailEnabled = false;  
        public bool UserMailEnabled  
        {  
            get  
            {  
                return this.userMailEnabled;  
            }  
            set  
            {  
                if (!userMailEnabled == value)  
                {  
                    this.userMailEnabled = value;  
                    OnPropertyChanged("UserMailEnabled");  
                }  
            }  
        }  
    
        private bool mobileEnabled = false;  
        public bool MobileEnabled  
        {  
            get  
            {  
                return this.mobileEnabled;  
            }  
            set  
            {  
                if (!mobileEnabled == value)  
                {  
                    this.mobileEnabled = value;  
                    OnPropertyChanged("MobileEnabled");  
                }  
            }  
        }  
    
        private bool addressEnabled = false;  
        public bool AddressEnabled  
        {  
            get  
            {  
                return this.addressEnabled;  
            }  
            set  
            {  
                if (!addressEnabled == value)  
                {  
                    this.addressEnabled = value;  
                    OnPropertyChanged("AddressEnabled");  
                }  
            }  
        }  
    
        private bool countryEnabled = false;  
        public bool CountryEnabled  
        {  
            get  
            {  
                return this.countryEnabled;  
            }  
            set  
            {  
                if (!countryEnabled == value)  
                {  
                    this.countryEnabled = value;  
                    OnPropertyChanged("CountryEnabled");  
                }  
            }  
        }  
    
        private bool cityEnabled = false;  
        public bool CityEnabled  
        {  
            get  
            {  
                return this.cityEnabled;  
            }  
            set  
            {  
                if (!cityEnabled == value)  
                {  
                    this.cityEnabled = value;  
                    OnPropertyChanged("CityEnabled");  
                }  
            }  
        }  
    
        private bool zippostalcodeEnabled = false;  
        public bool ZippostalcodeEnabled  
        {  
            get  
            {  
                return this.zippostalcodeEnabled;  
            }  
            set  
            {  
                if (!zippostalcodeEnabled == value)  
                {  
                    this.zippostalcodeEnabled = value;  
                    OnPropertyChanged("ZippostalcodeEnabled");  
                }  
            }  
        }  
    
        private bool firstnameEnabled = false;  
        public bool FirstnameEnabled  
        {  
            get  
            {  
                return this.firstnameEnabled;  
            }  
            set  
            {  
                if (!firstnameEnabled == value)  
                {  
                    this.firstnameEnabled = value;  
                    OnPropertyChanged("FirstnameEnabled");  
                }  
            }  
        }  
    
        private bool lastnameEnabled = false;  
        public bool LastnameEnabled  
        {  
            get  
            {  
                return this.lastnameEnabled;  
            }  
            set  
            {  
                if (!lastnameEnabled == value)  
                {  
                    this.lastnameEnabled = value;  
                    OnPropertyChanged("LastnameEnabled");  
                }  
            }  
        }  
    
        private bool loadingFinished = false;  
        public bool LoadingFinished {  
            get {  
                return this.loadingFinished;  
            }  
            set {  
                if (value != this.loadingFinished) {  
                    this.loadingFinished = value;  
                    OnPropertyChanged("LoadingFinished");  
                }  
            }  
    

    And my Content Page:

        public partial class AccountPage : ContentPage  
        {  
            private Logger logger = App.Logger;  
            private AccountViewModel viewModel;  
            private bool buttonEventInProgress = false;  
      
      
            public AccountPage()  
            {  
                InitializeComponent();  
      
                if (Device.RuntimePlatform == Device.iOS)  
                {  
                    this.Padding = new Thickness(0, 30, 0, 0);  
                }  
      
                this.viewModel = new AccountPageViewModel();  
                this.BindingContext = this.viewModel;  
                this.viewModel.UserMail = App.AppBrain.UserProfile.Mail;  
                this.viewModel.MobileNumber = UserProfile.MobileNumber;  
                  
                var timer = new System.Threading.Timer(  
                    e => this.viewModel.refreshActiveTickets(),  
                    null,  
                    TimeSpan.Zero,  
                    TimeSpan.FromSeconds(2));  
      
            }  
    

  3. Fadi H Rezq 11 Reputation points
    2021-03-22T12:03:26.05+00:00

    Hi... I have the exact issue that Dan is facing.

    This was originally a Xamarin.Forms 4.4 (or 4.5 I don't remember) project and Visual Studio 2019 that was not the latest version.
    The exact screen setup was working fine.
    I tried updating to AndroidX instead of the older Support Library and starting having issues with dependencies and r8 was removing some needed classes and a whole lot of stuff. Eventually I ended up updating to Xamarin.Forms 5 and the latest Visual Studio and all the latest NuGet packages.

    This seemed to solve all the issues I had but this particular issue reported here came which wasn't there before.

    I'm using Xamarin.Forms 5.0.0.2012
    VS Studio 2019 16.9.2
    Xamarin 16.9.000.273
    Xamarin.Android SDK 11.2.2.1

    My setup is a little different. Just a StackLayout inside of a ScrollView with the StackLayout dynamically populated with other controls:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="gulfHRXF.Pages.FormPage"
                 BackgroundColor="{DynamicResource ThemeBackgroundColor}">
        <ContentPage.Content>
            <ScrollView>
                <StackLayout x:Name="formScreenLayout" Margin="{StaticResource ThickMargin}" >
                </StackLayout>
            </ScrollView>
        </ContentPage.Content>
    </ContentPage>
    

    I'd appreciate any help at all. Thanks!

    0 comments No comments