作者:求道金林 | 来源:互联网 | 2023-01-31 18:04
我有一个非常大的形式(主要适用于平板电脑),有一个TabbedPage
嵌套a ScrollView
和一个StackPanel
包含许多控件的垂直.
我很少出现一个ListView
包含几个单行项目的地方,我需要它来确定内容的大小.
我想摆脱它的滚动条,但无论如何我不希望它占用比它的项目所需的空间更多的空间.
有没有办法(甚至是丑陋的)无需编写渲染器x3平台即可实现这一目标?
这是描述我的树的伪:
渲染后,有一个巨大的差距后ListView
.我怎么能避免这种情况?
我试着搞乱了,VerticalOptions
并且HeightRequest
没有工作.
我正在寻找一种动态方式(最好没有继承)来实现这一点,而不涉及自定义渲染器.
1> Shimmy..:
根据Lutaaya的回答,我做了一个自动执行此操作的行为,确定并设置行高(Gist).
行为:
namespace Xamarin.Forms
{
using System;
using System.Linq;
public class AutoSizeBehavior : Behavior
{
ListView _ListView;
ITemplatedItemsView Cells => _ListView;
protected override void OnAttachedTo(ListView bindable)
{
bindable.ItemAppearing += AppearanceChanged;
bindable.ItemDisappearing += AppearanceChanged;
_ListView = bindable;
}
protected override void OnDetachingFrom(ListView bindable)
{
bindable.ItemAppearing -= AppearanceChanged;
bindable.ItemDisappearing -= AppearanceChanged;
_ListView = null;
}
void AppearanceChanged(object sender, ItemVisibilityEventArgs e) =>
UpdateHeight(e.Item);
void UpdateHeight(object item)
{
if (_ListView.HasUnevenRows)
{
double height;
if ((height = _ListView.HeightRequest) ==
(double)VisualElement.HeightRequestProperty.DefaultValue)
height = 0;
height += MeasureRowHeight(item);
SetHeight(height);
}
else if (_ListView.RowHeight == (int)ListView.RowHeightProperty.DefaultValue)
{
var height = MeasureRowHeight(item);
_ListView.RowHeight = height;
SetHeight(height);
}
}
int MeasureRowHeight(object item)
{
var template = _ListView.ItemTemplate;
var cell = (Cell)template.CreateContent();
cell.BindingCOntext= item;
var height = cell.RenderHeight;
var mod = height % 1;
if (mod > 0)
height = height - mod + 1;
return (int)height;
}
void SetHeight(double height)
{
//TODO if header or footer is string etc.
if (_ListView.Header is VisualElement header)
height += header.Height;
if (_ListView.Footer is VisualElement footer)
height += footer.Height;
_ListView.HeightRequest = height;
}
}
}
|
用法: