更改控件边界以适应动态内容的简单方法?

发布于 2024-10-16 23:48:54 字数 298 浏览 3 评论 0原文

我希望控件的边界调整大小以适合其所有动态内容,这会改变每一帧。换句话说,如果我通过任何方式(画布、边框等)在控件上显示边界框,则该框应包含所有可见内容,其中可见内容的左上角是盒子。所有东西都应该装在盒子里。

内容的特殊之处在于它们每一帧都会改变,并且根据外部源的参数绘制在各处。我将控件的当前高度和宽度设置为“自动” - 这可以很好地确保显示所有内容 - 但不幸的是,控件的左上角值不会对应于所有内容的左上角可见内容。

有没有一种简单的方法可以使控件的边界更改以包含其所有内容?正如我上面所说,如果我显示了一个边界框,那么该框应该只包含所有可见内容。

I want a control's bounds to resize to JUST fit all of its dynamic content, which changes every frame. In other words, if I show a bounding box on the control via any means (canvas, border, etc.), that box should contain all of the visible content, where the top left corner of the visible content is the top left corner of the box. Everything should be JUST contained within the box.

The contents are special in that they change every frame, and are drawn all over the place based on parameters from an external source. I have the current height and width of the control set to 'auto' - which works well in ensuring that all content is displayed - but unfortunately the left-top corner value of the control will NOT correspond to the left-top of the all the visible content.

Is there an easy way to make the control's bounds change to contain all its content? As I said above, if I showed a bounding box, that box should JUST contain all of the visible content.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

香草可樂 2024-10-23 23:48:54

您没有说明如何定位控件的子元素,但子元素是相对于控件的,因此您需要控件缩小其空白的左侧和顶部区域,然后移动控件本身,以便所有内容都保留在您放置的位置。实现此目的的一种方法是编写一个类似于 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.TopCanvas.Left画布

You don't say how you position the child elements of the control but the child element are relative to the control so you need the control to shrink its blank left and top regions and then move the control itself so that everything stays where you put it. One way to do this is to write a custom panel similar to a Canvas.

Here is a prototype BoundingCanvas that tries to bound its position and size to the bounds of its children:

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));
    }
}

and you can use it like this:

<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>

The prototype needs more error checking and special case handling but it demonstrates the concept. In this example, the panel compensates for the adjusted size with an extra margin but you could also manipulate Canvas.Top and Canvas.Left if the intended parent was a Canvas.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文