如何获得WPF可视化的子元素的边界框,不包括父元素

本文关键字:元素 不包括 边界 何获得 WPF 可视化 | 更新日期: 2023-09-27 18:07:31

来自MSDN文档中的visualtreehelper . get后裔边界():

// Return the bounding rectangle of the parent visual object and all of its descendants.
Rect rectBounds = VisualTreeHelper.GetDescendantBounds(parentVisual);

我得到这个,它工作,但我想要包含父的边界,原因是我的父是一个XPS文档的页面,所以调用它只是返回页面边界,这不是我想要的。我想要页面上所有内容的边界框,也就是说,只是页面可视化的子元素。

// snippet of my code
Visual visual = paginator.GetPage(0).Visual;
Rect contentBounds = VisualTreeHelper.GetDescendantBounds(visual);
// above call returns the page boundaries
// is there a way to get the bounding box of just the children of the page?

我需要这个的原因是我要把XPS页面保存为位图,需要包含尽可能少的空白,以限制位图只在页面的"使用"区域。

我需要迭代所有的孩子的视觉自己和调用VisualTreeHelper.GetContentBounds()上每一个?

如何获得WPF可视化的子元素的边界框,不包括父元素

我提出了一个可行的解决方案,即枚举父(页面)视觉效果的所有子视觉效果。一个更有效的和/或库的解决方案会更好,但这是目前工作。

// enumerate all the child visuals
List<Visual> children = new List<Visual>();
EnumVisual(visual, children);
// loop over each child and call GetContentBounds() on each one
Rect? contentBounds = null;
foreach (Visual child in children)
{
    Rect childBounds = VisualTreeHelper.GetContentBounds(child);
    if (childBounds != Rect.Empty)
    {
        if (contentBounds.HasValue)
        {
            contentBounds.Value.Union(childBounds);
        }
        else
        {
            contentBounds = childBounds;
        }
    }
}
/// <summary>
/// Enumerate all the descendants (children) of a visual object.
/// </summary>
/// <param name="parent">Starting visual (parent).</param>
/// <param name="collection">Collection, into which is placed all of the descendant visuals.</param>
public static void EnumVisual(Visual parent, List<Visual> collection)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
        // Get the child visual at specified index value.
        Visual childVisual = (Visual)VisualTreeHelper.GetChild(parent, i);
        // Add the child visual object to the collection.
        collection.Add(childVisual);
        // Recursively enumerate children of the child visual object.
        EnumVisual(childVisual, collection);
    }
}