Простой способ изменить границы элемента управления для соответствия динамическому контенту - PullRequest
1 голос
/ 12 февраля 2011

Я хочу, чтобы границы элемента управления изменялись так, чтобы они соответствовали всему его динамическому контенту, который меняет каждый кадр.Другими словами, если я показываю ограничивающий прямоугольник на элементе управления любым способом (холст, граница и т. Д.), Этот блок должен содержать весь видимый контент, где верхний левый угол видимого контента является верхним левым угломкоробка.Все должно быть ПРОСТО помещено в рамку.

Содержимое отличается тем, что оно меняет каждый кадр и рисуется повсюду на основе параметров из внешнего источника.У меня есть текущая высота и ширина элемента управления, установленная на «auto», что хорошо работает для обеспечения отображения всего содержимого, но, к сожалению, значение левого верхнего угла элемента управления НЕ будет соответствовать левому верхнему углу всех элементов.видимое содержимое.

Существует ли простой способ изменить границы элемента управления, чтобы он содержал все его содержимое?Как я уже говорил выше, если я показал ограничивающий прямоугольник, он должен ПРОСТО содержать весь видимый контент.

1 Ответ

2 голосов
/ 12 февраля 2011

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

...