Formsban, ha egy ListView HorizontalOptions, VerticalOptions tulajdonságait Fill-re állítjuk, és a ListView egy Grid sorában van mondjuk, amelynek a Height-je Auto, a lista le fogja foglalni a Grid által kínált összes helyet. Ez azért van, mert a ListView measure-nél még nem tudja hogy milyen listaelemek milyen listaelem formátummal fognak megjelenni benne. Így elveszítjük a lehetőséget a dinamikus megjelenítésre, mert a felületünk szét fog csúszni.
Ennek a problémakörnek megoldásaképpen készítettem egy olyan ListView-t, amely képes a listaelemek tényleges lemért magassága után újraméretezni a lista magasságát. Ez a lista, mindig a benne található elemek magassága méretűre fog nyúlni. Meg lehet még fűszerezni annyival, hogy a Separatorok magasságát is beleszámolja, illetve hogy legyen egy maximálisan engedett magassága is, én ezt nem tettem meg, de jó kiindulási alap.
public class AutoHeightListView : ListView { public AutoHeightListView() { } protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) { base.OnPropertyChanged(propertyName); // ItemsSource változásakor if (propertyName == nameof(ListView.ItemsSource)) { if(ItemsSource != null) { // Kikérjük a ListView feltemapltezett celljeit. IEnumerable<PropertyInfo> pInfos = (this as ItemsView<Cell>).GetType().GetRuntimeProperties(); var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems"); if (templatedItems != null) { var cells = templatedItems.GetValue(this); if(cells is Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell> cellsCasted) { if(cellsCasted.Count != 0) { ((ViewCell)cellsCasted.Last()).View.SizeChanged += FirstElementHeightChanged; } } } } } } double prevHeight = 0; private void FirstElementHeightChanged(object sender, EventArgs e) { SetHeightRequestByCellsHeight(); } /// <summary> /// Megméri minden sor Viewcell magasságát, és az egész listview magasságát ezeknek az összegére állítja be. /// </summary> private void SetHeightRequestByCellsHeight() { double calculatedHeight = 0; // Kikérjük a ListView feltemapltezett celljeit. IEnumerable<PropertyInfo> pInfos = (this as ItemsView<Cell>).GetType().GetRuntimeProperties(); var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems"); if (templatedItems != null) { var cells = templatedItems.GetValue(this); foreach (ViewCell cell in cells as Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell>) { calculatedHeight += cell.View.Height; } } if (calculatedHeight == prevHeight) return; prevHeight = calculatedHeight; HeightRequest = calculatedHeight; } }