在WPF中获取控件的可见大小

4

我有一个控件,当窗口缩小时,它无法完全显示。 但是该控件的ActualWidth和RenderSize/DesiredSize仍然显示其总大小。 我编写了下面的代码,但它忽略了窗口滚动条的宽度,看起来很丑陋。 也许有一种更优雅的方法来获取控件的可见大小?

    private static double GetVisibleWidth(UIElement element, FrameworkElement container)
    {
        var visibleBounds =
            element.TransformToAncestor(container)
                .TransformBounds(new Rect(new Point(0, 0), element.RenderSize));

        double visibleWidth = element.RenderSize.Width;
        if (container != null)
        {
            visibleWidth = Math.Min(container.ActualWidth - visibleBounds.X, visibleWidth);
        }

        return visibleWidth;
    }

What size i am speaking about

2个回答

2

LayoutInformation.GetLayoutClip 可能是您需要的。

返回表示元素可见区域的几何图形。

但请注意,如果 element.IsArrangeValid && element.IsMeasureValid == false,则会返回 null。以下是您可以使用的方法:

private Size GetVisibleSize(FrameworkElement element)
{
    Rect? bounds = LayoutInformation.GetLayoutClip(element)?.Bounds;
    if (bounds == null)
    {
        return new Size(element.ActualWidth, element.ActualHeight);
    }
    return new Size(bounds.Value.Width, bounds.Value.Height);
}

如果您的元素在滚动查看器中,则此方法将无法正常工作,因为它在技术上并未剪裁。


LayoutInformation.GetLayoutClip对于元素及其可视化父级返回null。我猜测在我的情况下IsMeasureValid为false。 - l1pton17

1

我们选择元素,沿着视觉树向上查找,同时寻找元素与其父级之间的交点。

在这里...

private Rect GetVisibleBounds(UIElement element)
{
    var currentBounds = new Rect(element.PointToScreen(new Point(0, 0)), element.RenderSize);
    var container = VisualTreeHelper.GetParent(element) as FrameworkElement;
    while (container is not null)
    {
        var containerBounds = new Rect(container.PointToScreen(new Point(0, 0)), container.RenderSize);
        currentBounds.Intersect(containerBounds);
        container = VisualTreeHelper.GetParent(container) as FrameworkElement;
    }

    return currentBounds;
}

工作得很好,除了有时候你没有与父级交叉。我不确定为什么。如果在IsEmpty返回true时跳过交叉分配,它仍然可以工作。此外,此答案不考虑dpi缩放。您必须将缩放乘以RenderSize。位置已经在屏幕坐标中。不用说,返回值始终是屏幕坐标。 - Neijwiert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接