Как получить ограничивающую рамку дочерних элементов визуала WPF, исключая родительский - PullRequest
2 голосов
/ 06 сентября 2011

Из документации MSDN для VisualTreeHelper.GetDescendantBounds () :

// 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 () для каждого из них? Я думал, что будет лучший способ, чем сделать это ...

1 Ответ

2 голосов
/ 06 сентября 2011

Я придумал работоспособное решение, перечислив все дочерние визуальные элементы родительского (страницы) визуального.Было бы лучше более эффективное и / или библиотечное решение, но пока это работает.

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