question

DanRob-9330 avatar image
0 Votes"
DanRob-9330 asked ·

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

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>




dotnet-xamarinforms
· 1
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Could you share a demo about it, I used your code(I do not what is your style and binding value). So I just test with static value, here are running screenshot. The Bottom button could run normally.

77749-image.png


0 Votes 0 ·
image.png (74.6 KiB)
DanRob-9330 avatar image
0 Votes"
DanRob-9330 answered ·

@LeonLu-MSFT
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));
    
         }
· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I try to add your shared background code, but I still cannot reproduce your issue, provide a demo may be a better and faster choose.

0 Votes 0 ·
FadiHRezq-2623 avatar image
0 Votes"
FadiHRezq-2623 answered ·

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!

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

FadiHRezq-2623 avatar image
0 Votes"
FadiHRezq-2623 answered ·

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!


·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.