如何获取 WPF 视觉对象的子级的边界框(不包括父级)

发布于 2024-12-02 20:14:54 字数 968 浏览 8 评论 0原文

VisualTreeHelper.GetDescendantBounds() 的 MSDN 文档中:

// 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( ) 每一个?我认为有比这样做更好的方法......

From the MSDN documentation for VisualTreeHelper.GetDescendantBounds():

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

I get this and it works, but I do not want to include the parent's bounds, the reason is that my parent is a page of an XPS document, and so calling this just returns the page boundaries, which is not what I want. I want the bounding box of everything on the page, i.e. just of the children of the page visual.

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

The reason I need this is that I'm saving the XPS page to a bitmap and need to include as little white space as possible, to limit the bitmap to only the 'used' area of the page.

Do I need to iterate over all the children of the visual myself and call VisualTreeHelper.GetContentBounds() on each one? I thought there would be a better way than doing this...

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

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

发布评论

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

评论(1

爱本泡沫多脆弱 2024-12-09 20:14:54

我通过枚举父(页面)视觉对象的所有子视觉对象提出了一个可行的解决方案。更高效和/或库解决方案会更好,但这目前有效。

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

I've come up with a workable solution by enumerating over all the child visuals of the parent (page) visual. A more efficient and/or library solution would be better, but this works for now.

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