我想要一个控件的边界来调整大小以适应它的所有动态内容,这会改变每一帧。换句话说,如果我通过任何方式(画布,边框等)在控件上显示边框,则该框应包含所有可见内容,其中可见内容的左上角是左上角盒子。一切都应该只是包含在框内。
内容的特殊之处在于它们会改变每一帧,并根据来自外部源的参数在整个地方绘制。我将控件的当前高度和宽度设置为“自动” - 这可以很好地确保显示所有内容 - 但不幸的是,控件的左上角值不会对应于所有内容的左上角可见内容。
是否有一种简单的方法可以使控件的边界更改为包含其所有内容?如上所述,如果我显示了一个边界框,那个框应该只包含所有可见内容。
答案 0 :(得分:2)
您没有说明如何定位控件的子元素,但子元素是相对于控件的,因此您需要控件缩小其空白的左侧和顶部区域,然后移动控件本身以使所有内容都保持在你把它。一种方法是编写类似于Canvas
的自定义面板。
这是一个原型BoundingCanvas
,试图将其位置和大小绑定到其子节点:
public class BoundingCanvas : Panel
{
public BoundingCanvas()
{
HorizontalAlignment = HorizontalAlignment.Left;
VerticalAlignment = VerticalAlignment.Top;
}
private Vector minTopLeft;
protected override Size MeasureOverride(Size availableSize)
{
var resultSize = new Size();
minTopLeft = new Vector(double.PositiveInfinity, double.PositiveInfinity);
var unlimitedSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
foreach (UIElement child in Children)
{
child.Measure(unlimitedSize);
var topLeft = GetTopLeft(child);
minTopLeft.X = Math.Min(minTopLeft.X, topLeft.X);
minTopLeft.Y = Math.Min(minTopLeft.Y, topLeft.Y);
resultSize.Width = Math.Max(resultSize.Width, topLeft.X + child.DesiredSize.Width);
resultSize.Height = Math.Max(resultSize.Height, topLeft.Y + child.DesiredSize.Height);
}
resultSize.Width -= minTopLeft.X;
resultSize.Height -= minTopLeft.Y;
return resultSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
Margin = new Thickness(minTopLeft.X, minTopLeft.Y, 0, 0);
foreach (UIElement child in Children)
child.Arrange(new Rect(GetTopLeft(child) - minTopLeft, child.DesiredSize));
return finalSize;
}
private Point GetTopLeft(UIElement element)
{
return new Point(Canvas.GetLeft(element), Canvas.GetTop(element));
}
}
你可以像这样使用它:
<Grid>
<local:BoundingCanvas Background="Pink">
<Rectangle Canvas.Top="10" Canvas.Left="10" Width="10" Height="10" Fill="DarkRed"/>
<Rectangle Canvas.Top="20" Canvas.Left="20" Width="10" Height="10" Fill="DarkRed"/>
</local:BoundingCanvas>
</Grid>
原型需要更多的错误检查和特殊的案例处理,但它展示了这个概念。在此示例中,面板会使用额外的边距补偿调整后的尺寸,但如果目标父级为Canvas.Top
,您还可以操纵Canvas.Left
和Canvas
。