动态隐藏 Xamarin Forms ListView 项并将不可见项的高度设置为 0,这在 iOS 上不起作用



在 Xamarin Forms ListView 中,StackLayout 放置在 ViewCell 中。以下触发器用于将 StackLayout 的高度和边距设置为 0,以便列表视图中没有间隙。

<StackLayout.Triggers>
<Trigger TargetType="StackLayout" Property="IsVisible" Value="False">
<Setter Property="HeightRequest" Value="0" />
<Setter Property="Margin" Value="0" />
</Trigger>
</StackLayout.Triggers>

该代码在Android上运行良好。但是iOS上仍然存在差距。

通常,在点击事件上调用 ViewCell.ForceUpdateSize 可以帮助解决此类问题。但我们需要在语法上做到这一点。所以我尝试创建一个自定义视图单元格,但它没有帮助。

public class CustomViewCell : ViewCell
{
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
var viewModel = (tecommobile.ViewModels.Input)BindingContext;
viewModel.PropertyChanged += (sender, e) =>
{
if (Device.RuntimePlatform == Device.iOS)
{
if (e.PropertyName == "IsVisible")
{
//ForceUpdateSize(); crashes, the possible cause could be the height of the StackLayout is already set to 0. The test shows that the tapped event doesn't fire if the height is 0.
}
}
};
}
}

请告知解决方案或任何解决方法。谢谢。

我们应该使用TriggerAction来更改此值,并告诉ViewCell更新其大小。

public class ForceUpdateSizeTriggerAction : TriggerAction<VisualElement>
{
public double HeighRequest { set; get; }  // you could set it as bindable property if you want to binding its value in runtime
public Thickness CustomMargin { set; get; }
public ForceUpdateSizeTriggerAction() : base()
{
}
protected override void Invoke(VisualElement sender)
{
var parent = sender.Parent;
while (parent != null && !(parent is ViewCell))
{
parent = parent.Parent;
}
if (parent is ViewCell cell)
{
Device.BeginInvokeOnMainThread(() =>
{
var view = sender as View;
view.HeightRequest = HeighRequest;
view.Margin = CustomMargin;
cell.ForceUpdateSize();
});
}
}
}

在 XAML 中

<StackLayout.Style>
<Style TargetType="StackLayout">
<Setter Property="HeightRequest" Value="xxx"/> //default height
<Style.Triggers>
<DataTrigger TargetType="StackLayout" Binding="{Binding xxx}"  Value="False">  /// xxx here is the property which binding to the IsVisible of stacklayout
<DataTrigger.EnterActions>
<local:ForceUpdateSizeTriggerAction HeighRequest="0.01" CustomMargin="0"/>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<local:ForceUpdateSizeTriggerAction HeighRequest="xxx" CustomMargin="xxx"/> // set the default value of height and margin here
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</StackLayout.Style>

并且不要忘记设置列表视图HasUnevenRows="True"

最新更新