我需要创建如下UI(一种标签云控件)
我尝试过以下事情
有什么想法吗?
答案 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>