Mark A. Donohoe
Mark A. Donohoe

Reputation: 30378

How can you get the Rect passed to a UIElement's Arrange method during the base implementation of ArrangeOverride for any given panel subclass?

In a DockPanel subclass's ArrangeOverride method, the first thing we do is call the base implementation as that's who handles the actual arrangement. However, without going into the 'why' here (as it's not relevant to the question), we then need to get the Rect which the base implementation of ArrangeOverride passed to the Arrange method of the last child.

Is there any way to query a UIElement to see what rect was passed to its Arrange method?

For instance...

protected override Size ArrangeOverride(Size arrangeSize)
{
    // Perform default arrangement
    var retVal = base.ArrangeOverride(arrangeSize);

    // Get the last element (if any)
    var lastElement = Children.OfType<UIElement>().LastOrDefault();

    // Get the Rect passed to the lastElement in the base.ArrangeOverride call
    var lastElementArrangeRect = (lastElement != null)
         ? lastElement.ArrangeRect // <-- This is what we're looking for
         : new Rect();

    return retVal;
}

The only way we have found is to re-implement ArrangeOverride ourselves as we would then obviously know the Rect used. However, we're trying to have code that will work with any panel subclass.

Upvotes: 0

Views: 714

Answers (1)

Il Vic
Il Vic

Reputation: 5666

In my opinion you can use reflection. By spying the Arrange method in the UIElement class you will find that a private field (called _finalRect) is set with the value of finalRect parameter of the Arrange method itself.

This is not always true: it depends on some if conditions (you just need to see the code). You can also notice that the _finalRect private field is returned by the PreviousArrangeRect property (it is an internal property).

Now all you need is a static helper method for retrieving the value of that property:

public static Rect GetPreviousArrangeRect(UIElement element)
{
    Type elementType;
    PropertyInfo propertyInfo;

    if (element != null)
    {
        elementType = element.GetType();
        propertyInfo = elementType.GetProperty("PreviousArrangeRect",
            BindingFlags.Instance | BindingFlags.NonPublic);

        return (Rect)propertyInfo.GetValue(element, null);
    }

    return Rect.Empty;
}

Now I do not know what is your exact issue, but I hope this hint can help you in solving it.

Upvotes: 1

Related Questions