我可以创建一个事件处理程序,考虑到ListView单元格的大小变化。以下是代码:
<ListView ItemsSource="{Binding Items}"
VerticalOptions="Start"
HasUnevenRows="true"
CachingStrategy="RecycleElement"
SelectionMode="None"
SizeChanged="ListView_OnSizeChanged">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<Frame Padding="10,0" SizeChanged="VisualElement_OnSizeChanged">
通过使用Grid、StackLayout等控件,可以改变框架。
xaml.cs:
static readonly Dictionary<ListView, Dictionary<VisualElement, int>> _listViewHeightDictionary = new Dictionary<ListView, Dictionary<VisualElement, int>>();
private void VisualElement_OnSizeChanged(object sender, EventArgs e)
{
var frame = (VisualElement) sender;
var listView = (ListView)frame.Parent.Parent;
var height = (int) frame.Measure(1000, 1000, MeasureFlags.IncludeMargins).Minimum.Height;
if (!_listViewHeightDictionary.ContainsKey(listView))
{
_listViewHeightDictionary[listView] = new Dictionary<VisualElement, int>();
}
if (!_listViewHeightDictionary[listView].TryGetValue(frame, out var oldHeight) || oldHeight != height)
{
_listViewHeightDictionary[listView][frame] = height;
var fullHeight = _listViewHeightDictionary[listView].Values.Sum();
if ((int) listView.HeightRequest != fullHeight
&& listView.ItemsSource.Cast<object>().Count() == _listViewHeightDictionary[listView].Count
)
{
listView.HeightRequest = fullHeight;
listView.Layout(new Rectangle(listView.X, listView.Y, listView.Width, fullHeight));
}
}
}
private void ListView_OnSizeChanged(object sender, EventArgs e)
{
var listView = (ListView)sender;
if (listView.ItemsSource == null || listView.ItemsSource.Cast<object>().Count() == 0)
{
listView.HeightRequest = 0;
}
}
当 Frame 显示时(ListView.ItemTemplate 应用时),Frame 的大小会发生变化。
我们通过 Measure() 方法获取其实际高度,并将其放入字典中,该字典知道当前 ListView 并保存 Frame 的高度。当显示最后一个 Frame 时,我们将所有高度相加。
如果没有项目,则 ListView_OnSizeChanged() 将 listView.HeightRequest 设置为 0。
ListView
自适应其所需的高度,可选地设置最大高度。 - Shimmy Weitzhandler