I am developing a Xamarin Forms app in Visual Studio 2019 using the standard Android emulator. The XAML contains a ScrollView that contains a Grid. The grid merely has two columns. I have a handler for the OnStart event that connects to a database, gets a response containing 64 objects, adds two labels to the grid for each object, and populates the labels. The ScrollView's background color is set to yellow. When I debug the app using the emulator, the initial screen is drawn correctly. But when I scroll down, the grid is not filled in. The background is still yellow, showing that the scrollview is the correct size (or at least, big enough to hold more labels). What am I doing wrong?
When I put a breakpoint at the bottom of the second for loop, after adding the labels, I see that I have all of the label objects I expect, and they have the text properties set as I expect.
Here's the XAML:
<?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="CapsBases.MainPage">
<ScrollView BackgroundColor="Yellow"
VerticalOptions="FillAndExpand">
<Grid Margin="10"
x:Name="BasesGrid">
<!-- two columns: base ID and status -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
</ScrollView>
</ContentPage>
The event handler calls a function named ShowBases() in the MainPage.xaml.cs file. Here it is:
public async void ShowBases()
{
string url = "http://10.0.2.2:5000/caps/bases";
//HttpClient client = new HttpClient();
//string info = await client.GetStringAsync(url);
//// await DisplayAlert("Coil Count", message, "Close");
//// The base ID and string will be returned in a single string with a space separating them.
//string[] pieces = info.Split(' ');
//BaseID.Text = pieces[0];
//BaseStatus.Text = pieces[1];
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
string data = await response.Content.ReadAsStringAsync();
//IEnumerable<Base> baseList = JsonConvert.DeserializeObject<IEnumerable<Base>>(data);
List<Base> baseList = JsonConvert.DeserializeObject<List<Base>>(data).OrderBy(b =>b.BaseName).ToList();
//BaseID.Text = theBase.BaseName;
//BaseStatus.Text = theBase.Status;
string message = $"Retrieved {baseList.Count()} bases.";
await DisplayAlert("Result", message, "Close");
Grid theGrid = BasesGrid;
var rowDefinitions = theGrid.RowDefinitions;
for (int i = 0; i < baseList.Count(); i )
{
RowDefinition rowDef = new RowDefinition { Height = 20 };
rowDefinitions.Add(rowDef);
}
await DisplayAlert("Row count", $"The grid has {BasesGrid.RowDefinitions.Count()} rows.", "Close");
// We have the grid with all the rows we need. Now we have to create a label for each grid cell.
try
{
for (int i = 0; i < baseList.Count(); i )
{
BasesGrid.Children.Add
(
new Label
{
Text = baseList[i].BaseName,
HorizontalOptions = LayoutOptions.Start
},
0, i
);
BasesGrid.Children.Add
(
new Label
{
Text = baseList[i].Status,
HorizontalOptions = LayoutOptions.Start
},
1, i
);
}
}
catch (Exception ex)
{
await DisplayAlert("Error", $"Failed to add row data: {ex.Message}", "Close");
}
}
else
{
await DisplayAlert("Get Coils failure",
$"Failed to retrieve coils; status code: {response.StatusCode}",
"Close");
}
}
}
}
CodePudding user response:
Surround the Grid in a StackLayout of vertical orientation. The Grid is not expanding inside the ScrollView.