Вы не говорите, как располагаете дочерние элементы элемента управления, но дочерний элемент относительно элемента управления, поэтому вам нужен элемент управления, чтобы уменьшить его пустую левую и верхнюю области, а затем переместить сам элемент управления, чтобы все осталось Вы положили это. Один из способов сделать это - написать пользовательскую панель, похожую на 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
.