如何使用Xamarin表单使按钮像标记云一样缠绕?

如何使用Xamarin表单使按钮像标记云一样缠绕?,xamarin,xamarin.forms,Xamarin,Xamarin.forms,我有这样的代码: <TableSection> <ViewCell Height="200"> <Button Text="ABCDEFG"></Button> <Button Text="ABCDEFG"></Button> <Button Text="ABCDEFG"></Button> <Button Text="ABCDEFG">

我有这样的代码:

<TableSection>
   <ViewCell Height="200">
      <Button Text="ABCDEFG"></Button>
      <Button Text="ABCDEFG"></Button>
      <Button Text="ABCDEFG"></Button>
      <Button Text="ABCDEFG"></Button>      
      <Button Text="ABCDEFG"></Button>
      <Button Text="ABCDEFG"></Button>
      <Button Text="ABCDEFG"></Button>
   </ViewCell>
</TableSection>

我想做的是使按钮看起来像标记云,并将ViewCell高度展开以适应它们

我没有看到任何我可以做到这一点的例子,我希望得到一些反馈/建议

谢谢

更新1-以下是我尝试的但无效的

   <ViewCell Height="200">
      <StackLayout Orientation="Horizontal" IsClippedToBounds="false" Spacing="5">
         <Button Text="ABCDEF1" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
         <Button Text="ABCDEF2" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
         <Button Text="ABCDEF3" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
         <Button Text="ABCDEF4" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
         <Button Text="ABCDEF5" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
         <Button Text="ABCDEF6" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
         <Button Text="ABCDEF7" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
         <Button Text="ABCDEF8" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30">
                                </Button>
      </StackLayout>
   </ViewCell>


不幸的是,我只看到了前四个按钮,之后什么都没有。我希望看到的是第一行上的按钮,然后是第二行上的另外四个按钮,视图单元格的高度可以根据需要扩展。

为什么不使用堆栈布局

<StackLayout Orientation="Horizontal" IsClippedToBounds="false" Spacing="5"  >
     <Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90" HeightRequest="30" ></Button> 
     <Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90"  HeightRequest="30" ></Button> 
     <Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90"  HeightRequest="30" ></Button> 
     <Button Text="ABCDEFG" TextColor="Blue" BackgroundColor="Transparent" WidthRequest="90"  HeightRequest="30" ></Button>  
</StackLayout>

您可以按照xamarin forms developers网站提供的指南实现这一点,网址为

您描述的问题与本指南中的示例代码完全相同。创建自定义布局您可以在任何需要的地方重用此解决方案

简而言之,创建WrapLayout需要做什么:

  • 执行处理子项的方法
  • 提供可绑定的属性,以便根据需要个性化使用
  • 随便吃吧
  • 您可能会得到如下结果:

    <TableSection>
       <ViewCell Height="200">
          <Button Text="ABCDEFG"></Button>
          <Button Text="ABCDEFG"></Button>
          <Button Text="ABCDEFG"></Button>
          <Button Text="ABCDEFG"></Button>      
          <Button Text="ABCDEFG"></Button>
          <Button Text="ABCDEFG"></Button>
          <Button Text="ABCDEFG"></Button>
       </ViewCell>
    </TableSection>
    

    正如迭戈所建议的,我们可以定制
    布局来实现预期风格

    创建新的子类,它派生自
    布局
    ,我们只需要

  • 覆盖测量上的
    以返回此布局的大小

  • 覆盖布局子项以确定子项的位置和大小

  • 创建
    可绑定属性
    ,根据需要个性化使用

  • 自定义布局:
    公共类播放:布局
    {
    公共静态只读BindableProperty SpacingProperty=
    BindableProperty.Create
    (
    “间距”,
    类型(双),
    类型(播放),
    10.0,
    propertyChanged:(可绑定、旧值、新值)=>((WrapLayout)可绑定)
    );
    公共双间距
    {
    获取{return(double)GetValue(SpacingProperty);}
    set{SetValue(SpacingProperty,value);}
    }
    私有void OnSizeChanged()
    {
    这是ForceLayout();
    }
    测量时受保护的覆盖大小请求(双宽度约束、双高度约束)
    {
    如果(请求宽度>0)
    widthConstraint=Math.Min(widthConstraint,WidthRequest);
    如果(高度请求>0)
    heightConstraint=Math.Min(heightConstraint,HeightRequest);
    double internalWidth=double.IsPositiveInfinity(宽度约束)?double.PositiveInfinity:Math.Max(0,宽度约束);
    double internalHeight=double.IsPositiveInfinity(高度约束)?double.PositiveInfinity:Math.Max(0,高度约束);
    返回DoHorizontalMeasure(内部宽度、内部高度);
    }
    专用尺寸要求DoHorizontalMeasure(双宽度约束、双高度约束)
    {
    int rowCount=1;
    双倍宽度=0;
    双倍高度=0;
    双最小宽度=0;
    双倍最小高度=0;
    使用的双宽度=0;
    foreach(子项中的变量项)
    {
    变量大小=项目度量(宽度约束、高度约束);
    高度=数学最大值(高度、大小、请求、高度);
    var newWidth=width+size.Request.width+space;
    如果(新宽度>宽度约束)
    {
    行计数++;
    宽度使用=数学最大值(宽度,宽度使用);
    宽度=size.Request.width;
    }
    其他的
    宽度=新宽度;
    最小高度=数学最大值(最小高度、大小、最小高度);
    minWidth=Math.Max(minWidth,size.Minimum.Width);
    }
    如果(行计数>1)
    {
    宽度=数学最大值(宽度,使用的宽度);
    高度=(高度+间距)*行数-间距;//通过MitchMilam
    }
    返回新大小请求(新大小(宽度、高度)、新大小(最小宽度、最小高度));
    }
    受保护的替代无效布局子项(双x、双y、双宽度、双高度)
    {
    双排高=0;
    双yPos=y,xPos=x;
    foreach(Children.Where中的var child(c=>c.IsVisible))
    {
    var请求=child.Measure(宽度、高度);
    double childWidth=request.request.Width;
    double childHeight=request.request.Height;
    rowHeight=Math.Max(rowHeight,childHeight);
    如果(xPos+childWidth>width)
    {
    xPos=x;
    yPos+=行高+间距;
    行高=0;
    }
    var region=新矩形(xPos、yPos、childWidth、childHeight);
    LayoutChildInboundingRegion(子级,区域);
    xPos+=区域。宽度+间距;
    }
    }
    }
    
    在圣诞节
    
    
    试验

    你能画出你想要达到的效果吗?我试过了,但它只适用于宽度相同的按钮。我知道这个示例显示它们的字符数都是相同的,但在实际代码中,它们的宽度变化很大。
    <local:WrapLayout Spacing="5">
        <Button Text="111111111111111" BackgroundColor="Red"/>
        <Button Text="222" BackgroundColor="Green"/>
        <Button Text="33333333333333333333333333" BackgroundColor="Gray"/>
        <Button Text="444444" BackgroundColor="Blue"/>
        <Button Text="5" BackgroundColor="Orange"/>
        <Button Text="6666666666666666" BackgroundColor="Aqua"/>
        <Button Text="77777777" BackgroundColor="Yellow"/>
        <Button Text="888" BackgroundColor="Pink"/>
        <Button Text="9 9 9 9" BackgroundColor="Purple"/>
        <Button Text="10" BackgroundColor="Brown"/>
    </local:WrapLayout>