在容器中创建n个可变大小的按钮

时间:2017-01-13 10:21:49

标签: xaml uwp win-universal-app winrt-xaml uwp-xaml

我需要创建如下UI(一种标签云控件)

  • n个按钮(计数将在运行时确定)
  • 根据内容
  • ,每个按钮的宽度不同
  • 连续最多3个按钮

Buttons with different widths

我尝试过以下事情

  • VariableSizedWrapGrid作为GridView的ItemsPanel(它需要RowSpan 和指定ColumnSpan,宽度为不可行 在运行期间确定)
  • 水平方向的StackPanel(所有按钮排列成一行)

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

基本上,VariableSizedWrapGrid会对其所有子节点进行相同的处理。您可以使用ColumnSpan和RowSpan来扩展子区域。

另一种方法是创建一个WrapPanel用户控件,然后使用它来代替VariableSizedWrapGrid。这将按照您的描述塑造输出。

答案 1 :(得分:2)

Here是关于如何根据您的要求创建WrapPanel的精彩博文。

我已根据此博客创建了一个TagsPanel,以便在我的某个应用中使用。关键是循环到项目并获取实际大小,并根据面板的可用宽度进行设置。见下文。

public class TagsPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        // Just take up all of the width
        Size finalSize = new Size { Width = availableSize.Width };
        double x = 0;
        double rowHeight = 0d;
        foreach (var child in Children)
        {
            // Tell the child control to determine the size needed
            child.Measure(availableSize);

            x += child.DesiredSize.Width;
            if (x > availableSize.Width)
            {
                // this item will start the next row
                x = child.DesiredSize.Width;

                // adjust the height of the panel
                finalSize.Height += rowHeight;
                rowHeight = child.DesiredSize.Height;
            }
            else
            {
                // Get the tallest item
                rowHeight = Math.Max(child.DesiredSize.Height, rowHeight);
            }
        }

        // Add the final height
        finalSize.Height += rowHeight;
        return finalSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        Rect finalRect = new Rect(0, 0, finalSize.Width, finalSize.Height);

        double rowHeight = 0;
        foreach (var child in Children)
        {
            if ((child.DesiredSize.Width + finalRect.X) > finalSize.Width)
            {
                // next row!
                finalRect.X = 0;
                finalRect.Y += rowHeight;
                rowHeight = 0;
            }
            // Place the item
            child.Arrange(new Rect(finalRect.X, finalRect.Y, child.DesiredSize.Width, child.DesiredSize.Height));

            // adjust the location for the next items
            finalRect.X += child.DesiredSize.Width;
            rowHeight = Math.Max(child.DesiredSize.Height, rowHeight);
        }
        return finalSize;
    }
}

并在GridView下面使用它。

<GridView ItemsSource="{Binding tags}" >
    <GridView.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding ''}" Margin="5"/>
        </DataTemplate>
    </GridView.ItemTemplate>
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <local:TagsPanel/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
</GridView>