所以我有一个垂直包裹的包装纸。这些项目是在运行时添加的,但是所有这些项目(用户控件)都有不同的宽度,并且因为wrappanel是垂直包装的,所以它们将它们堆叠起来,当它们覆盖垂直空间时,它们会包裹到下一列。但我需要的是“有点”双向包装,即我添加了宽度为200px的第一个项目,然后我添加了第二个项目,其宽度为50px,但是当我添加第三个项目,如100px in宽度我希望它不要去下一行,但是将自己置于那个50px控件留在那里的自由点,这取决于顶部的200px控件(留下150px空间和100px控件明显适合)。当然,当它不适合时,它会包裹到下一行,这一切都没问题。
这是一张图片来澄清这一点(这里不能上传'):
这就是发生的事情: image 1
这就是我想要的: image 2
对不起我的英语,这不是我的主要语言。我希望你能理解我的问题。
答案 0 :(得分:0)
你绝对不能使用单个面板来实现这一目标!您可以使用stackpanel在哪里插入多个动态包装带水平方向,以获得所需的“列”行为
答案 1 :(得分:0)
好吧,我做到了。刚刚用我想要的行为写了一个自定义的包装。
这是:
public class TwoWayWrapPanel : Panel
{
int _rowCount = 0;
public int RowCount
{
get { return _rowCount; }
set { _rowCount = value; }
}
protected override Size MeasureOverride(Size availableSize)
{
Size resultSize = new Size(0, 0);
double columnWidth = 0;
double usedSpace = 0;
double nullX = 0;
double currentX = 0;
double currentY = 0;
bool isFirst = true;
int row = 0;
foreach (UIElement child in Children)
{
child.Measure(availableSize);
if (isFirst)
{
columnWidth = child.DesiredSize.Width;
resultSize.Width += columnWidth;
currentY += child.DesiredSize.Height;
row++;
isFirst = false;
}
else
{
if (columnWidth >= usedSpace + child.DesiredSize.Width & _rowCount > 1)
{
currentX = nullX + usedSpace;
usedSpace += child.DesiredSize.Width;
}
else
{
row++;
if (row + 1 > _rowCount | child.DesiredSize.Width > columnWidth)
{
row = 0;
currentX = nullX + columnWidth;
nullX = currentX;
usedSpace = 0;
columnWidth = child.DesiredSize.Width;
currentY = child.DesiredSize.Height;
row++;
resultSize.Width += columnWidth;
}
else
{
currentY += child.DesiredSize.Height;
currentX = nullX;
usedSpace = child.DesiredSize.Width;
}
}
}
}
return resultSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
double columnWidth = 0;
double usedSpace = 0;
double nullX = 0;
double currentX = 0;
double currentY = 0;
bool isFirst = true;
int row = 0;
foreach (UIElement child in Children)
{
//First item in the collection
if (isFirst)
{
child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
columnWidth = child.DesiredSize.Width;
currentY += child.DesiredSize.Height;
row++;
isFirst = false;
}
else
{
//Current item fits so place it in the same row
if (columnWidth >= usedSpace + child.DesiredSize.Width & _rowCount > 1)
{
currentX = nullX + usedSpace;
child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
usedSpace += child.DesiredSize.Width;
}
else
{
row++;
//The row limit is reached or the item width is greater than primary item width. Creating new column
if (row + 1 > _rowCount | child.DesiredSize.Width > columnWidth)
{
row = 0;
currentY = 0;
currentX = nullX + columnWidth;
nullX = currentX;
usedSpace = 0;
child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
columnWidth = child.DesiredSize.Width;
currentY += child.DesiredSize.Height;
row++;
}
//Item doesn't fit. Adding to the new row in the same column
else
{
usedSpace = 0;
currentY += child.DesiredSize.Height;
currentX = nullX;
child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
usedSpace += child.DesiredSize.Width;
}
}
}
}
return finalSize;
}
}