Xamarin Forms: Auto magasságú ListView
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;
}
}
Tags In
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Hi, I am András,
I am a seasoned software engineer from Budapest, Hungary with a strong focus on mobile app development using .NET MAUI and Xamarin.Forms. My expertise also extends to website building for my happy customers and other complex system designing. I am passionate about developing well-organized, maintainable software solutions.