Xamarin.Forms ListView的大小可以显示内容吗? [英] Xamarin.Forms ListView size to content?

查看:305
本文介绍了Xamarin.Forms ListView的大小可以显示内容吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当大的表格(主要用于平板电脑),其中有一个TabbedPage嵌套一个ScrollView和一个垂直的StackPanel,其中包含许多控件.

I have a pretty large form (adapted mainly for tablets), that has a TabbedPage nesting a ScrollView and a vertical StackPanel containing many controls.

在出现ListView包含少量单行项目的情况时,我很少出现,因此我需要将其调整为适当的大小.
我想摆脱它的滚动条,但是无论如何我都不希望它占用比其项目所需更多的空间.
有没有一种方法(甚至是丑陋的方法)也可以实现,而无需编写渲染器x3平台?

I have few occurrences where I have a ListView that contains a few single-line items, and I need it to size to content.
I'd like to get rid of its scroll-bars, but anyway I don't want it to take up more space than what's required for its items.
Is there a way (even an ugly one) to achieve that without have to write a renderer x3 platforms?

这是描述我的树的伪造物:

Here's a pseudo describing my tree:

<ContentPage>
  <MasterDetailPage>
    <MasterDetailPage.Detail>
      <TabbedPage>
        <ContentPage>
          <ScrollView>
            <StackPanel>
              <!-- many controls-->
              <ListView>

渲染后,在ListView之后会有巨大的差距.我该如何避免呢?

When rendered, there is a huge gap coming after the ListView. How can I avoid that?

我尝试弄乱了VerticalOptionsHeightRequest,但都不起作用.

I tried messing around with the VerticalOptions and HeightRequest, non of which worked.

我正在寻找一种动态方式(最好是不继承)来实现这一目标,而无需涉及自定义渲染器.

I'm looking for a dynamic way (preferably without inheritance) to achieve that without involving custom renderers.

推荐答案

基于Lutaaya的 answer ,我的行为是可以自动执行此操作,确定并设置行高(要点).

Based on Lutaaya's answer, I made a behavior that automates this, determining and setting the row-height (Gist).

namespace Xamarin.Forms
{
  using System;
  using System.Linq;
  public class AutoSizeBehavior : Behavior<ListView>
  {
    ListView _ListView;
    ITemplatedItemsView<Cell> 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;
    }
  }
}

用法:

<ContentPage xmlns:xf="clr-namespace:Xamarin.Forms">
  <ListView>
    <ListView.Behaviors>
      <xf:AutoSizeBehavior />

这篇关于Xamarin.Forms ListView的大小可以显示内容吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆