C# 调整对象大小时在wrappanel中正确调整对象
很难用几句话来描述我的问题! 这就是我想要达到的目标 对象1通常填充其父对象的宽度。 它可以最小化到它以前宽度的一小部分,当这种情况发生时,它在其父对象中是右对齐的。对象2应自动向上滑动以填充间隙,并左对齐 我尝试过各种StackPanel、Wrappanel和DockPanel,但无法解决布局问题C# 调整对象大小时在wrappanel中正确调整对象,c#,wpf,stackpanel,wrappanel,C#,Wpf,Stackpanel,Wrappanel,很难用几句话来描述我的问题! 这就是我想要达到的目标 对象1通常填充其父对象的宽度。 它可以最小化到它以前宽度的一小部分,当这种情况发生时,它在其父对象中是右对齐的。对象2应自动向上滑动以填充间隙,并左对齐 我尝试过各种StackPanel、Wrappanel和DockPanel,但无法解决布局问题 有没有一种方法可以允许这种行为,而不必在代码背后进行大量难看的数学运算?嗯,我想出了一些办法。也许不是世界上最优雅的——但它适用于我的用例 public class CollapsingPanel
有没有一种方法可以允许这种行为,而不必在代码背后进行大量难看的数学运算?嗯,我想出了一些办法。也许不是世界上最优雅的——但它适用于我的用例
public class CollapsingPanel : Panel
{
/// <summary>
/// parents are supposed to ask their children what their desired size is, given an available size
/// </summary>
/// <param name="availableSize"></param>
/// <returns></returns>
protected override Size MeasureOverride(Size availableSize)
{
var availableSizeOnThisLine = new Rect(new Point(0, 0), new Size(availableSize.Width, 0));
var panelDesiredSize = new Size(availableSize.Width, 0);
foreach (FrameworkElement child in InternalChildren)
{
child.Measure(availableSize);
var childSize = child.DesiredSize;
if (childSize.Width > availableSizeOnThisLine.Size.Width)
{
// this child will overflow this line: New line!
panelDesiredSize.Height += availableSizeOnThisLine.Height;
availableSizeOnThisLine = new Rect(new Point(0, panelDesiredSize.Height), new Size(availableSize.Width, childSize.Height));
availableSizeOnThisLine.Width -= childSize.Width; // subtract this area/width
availableSizeOnThisLine.Height = childSize.Height;
}
else
{
// this child will fit on this line..
var thisChildRectangle = new Rect(childSize);
if (child.HorizontalAlignment == HorizontalAlignment.Left)
{
thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top);
availableSizeOnThisLine.Location.Offset(childSize.Width, 0); // move to the right
}
else if (child.HorizontalAlignment == HorizontalAlignment.Right)
{
thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - childSize.Width, availableSizeOnThisLine.Top);
}
child.Arrange(thisChildRectangle);
availableSizeOnThisLine.Width -= childSize.Width; // subtract child's width from avbailable space
availableSizeOnThisLine.Height = Math.Max(availableSizeOnThisLine.Height, childSize.Height);
panelDesiredSize.Height = Math.Max(childSize.Height, panelDesiredSize.Height);
}
}
return panelDesiredSize;
}
/// <summary>
/// parents position their children and tell their children how much size they are actually getting
/// </summary>
/// <param name="finalSize"></param>
/// <returns></returns>
protected override Size ArrangeOverride(Size finalSize)
{
var availableSizeOnThisLine = new Rect(new Point(0, 0), new Size(finalSize.Width, 0));
foreach (FrameworkElement child in InternalChildren)
{
var childSize = child.DesiredSize;
if (childSize.Width > availableSizeOnThisLine.Size.Width)
{
// going to wrap around
var thisChildRectangle = new Rect(child.DesiredSize);
availableSizeOnThisLine = new Rect(new Point(0, availableSizeOnThisLine.Height), new Size(finalSize.Width, childSize.Height));
if (child.HorizontalAlignment == HorizontalAlignment.Right)
{
thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - thisChildRectangle.Width, availableSizeOnThisLine.Top);
}
else if (child.HorizontalAlignment == HorizontalAlignment.Left)
{
thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top);
}
child.Arrange(thisChildRectangle);
}
else
{
// put on this line
var thisChildRectangle = new Rect(child.DesiredSize);
if (child.HorizontalAlignment == HorizontalAlignment.Right)
{
thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - thisChildRectangle.Width, availableSizeOnThisLine.Top);
}
else if (child.HorizontalAlignment == HorizontalAlignment.Left)
{
thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top);
}
child.Arrange(thisChildRectangle);
availableSizeOnThisLine.Width -= thisChildRectangle.Width; // subtract child's width from avbailable space
}
availableSizeOnThisLine.Height = Math.Max(childSize.Height, availableSizeOnThisLine.Height);
}
return finalSize;
}
调整1的大小,并在WrapPanel中对这两个重新排序。当然,在计算新尺寸时需要做一些数学运算。@kennyzx,你可能误解了这个问题。。。我不认为当第一个元素最小化时,包装将交换两个元素的顺序。。。是吗?1应该右对齐,2应该左对齐。这是我的主要问题。在此处设置HorizontalAlignment属性对您没有帮助。当对象被最小化时,也许您可以交换项目的实际位置?或者,您可以创建一个UserControl,将两个对象配对,并在适当的时候为您调整它们。。。然后将UserControls添加到WrapPanel。