Xamarin.Forms.GridView
Xamarin.Forms.GridView copied to clipboard
The item do not display if the height is set after loading (iOS)
It is me again.
So here is the issue I was facing : I have a grid view in a page declared in XAML. Like this :
<controls:GridView
x:Name="PicturesGrid"
Grid.RowSpan="2"
Grid.ColumnSpan="3"
Margin="-2,0,-2,0"
AutomationId="PicturesGrid"
GridItemTapped="OnPictureTapped"
HasUnevenRows="True"
IsGroupingEnabled="False"
ItemsSource="{Binding Pictures}"
TappedCommand="{Binding ToggleSelectionCommand}">
My issue is that I want square items (to display a picture gallery). So I set the RowHeight
and MinItemWidth
in the code behind in the OnAppearing
of my page to be sure to have the measurement of the page updated.
This gives me something like this :
protected override void OnAppearing()
{
this.PicturesGrid.MinItemWidth = Math.Floor(this.Width / 3);
this.PicturesGrid.RowHeight = (int)this.PicturesGrid.MinItemWidth;
}
My issue is that the first time I navigate to the page, nothing appeared. The RowHeight
not being set when the GridView
was initialized. So the ItemSize
was set to 0 and thus, no element was displayed. Then if I navigated away and came back to the page, the items were displaying right.
So I made a change to the code to be sure that the ItemSize
was updated when the RowHeight
property was changed :
Created the UpdateItemSize
method which does the same thing that was done in ElementSizeChanged
:
private void UpdateItemSize()
{
//Unbox the grid view.
var gridView = this.Element;
//Work out how many items can fit.
var canfit = (int)Math.Max(1, Math.Floor(gridView.Width / gridView.MinItemWidth));
//Stretch the width to fill row.
var actualWidth = gridView.Width / canfit;
//Set the item size accordingly.
_gridCollectionView.ItemSize = new CoreGraphics.CGSize(actualWidth, (float)gridView.RowHeight);
}
And the method is now called where the ItemSize
needs to be called (OnElementChanged
, ElementSizeChanged
and OnElementPropertyChanged
). The new OnElementPropertyChanged
method:
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var gridView = sender as GridView;
if (e.PropertyName == "ItemsSource")
{
if (gridView.ItemsSource != null)
{
_gridCollectionView.DataSource = DataSource;
ReloadData();
ScrollToInitialIndex();
}
}
if (e.PropertyName == "RowHeight")
{
this.UpdateItemSize();
}
}
So now, each time the RowHeight
is changed, the ItemSize
is changed accordingly.
Hope that helps.
Cheers, and thank you again for your work !