MesureOverride to return more than the availableSize?
Question
I was looking at FrameworkElement.MesureOverride on MSDN, trying to understand the mechanism behind the layout engine. I stumbled upon this interesting note :
During this process, child elements might return a larger DesiredSize size than the initial availableSize to indicate that the child element wants more space.
Ok. I had reflector near so I looked into MesureCore, which call MesureOverride and I noticed that, from what I could understand, the return value of MesureOverride is always capped between 0 and the availableSize. So what's up with that?
Solution
A child element can ask for more space. Whether that is honored by the parent element is up to the parent element.
MeasureCore only calls MeasureOverride on this
. You're only getting a very small part of the story. The Layout System starts with calling Measure
on the topmost Panel
in the tree of elements, which calls MeasureCore
on this
. However, MeasureCore
in FrameworkElement
calls MeasureOverride
in a couple of places.
Where are you seeing it cap between 0 and availableSize?
Edit: Re: "well, the last line of MeasureCore..."
Like I said, you're looking at a small part of all that goes on.
- All controls have 1 very common way to request more space than they actually need:
Margin
. You'd have to write a custom control to request even more space than that. - The constraints you see in
MeasureCore
, from what I can tell, have to do with theMinWidth
/MinHeight
andMaxWidth
/MaxHeight
limits, if they are set.
So yeah, a control -- like the documentation says -- can request more space than is needed. None of the default controls seem to do this aside from their Margin
s, and containers such as panels don't have to respect it. Most circumstances don't take advantage of what you read in the documentation because in most circumstances, it wouldn't make sense from either the perspective of the parent of the child.
If you created a UserControl
, got rid of the Width
and Height
values in the XAML and override MeasureOverride
to return an arbitrary Size
, then place an instance of it in a Canvas
, you would see it display at the Size
you returned.
This feature of the layout system may be of use if you are creating custom panels and custom controls or user controls, but otherwise probably not. But it is there. The documentation is correct.
OTHER TIPS
If you return a Size
> availableSize
from your own MeasureOverride
method, FrameworkElement.MeasureCore
(calling your method) will remember it, but DesiredSize
will be set = availableSize
. This guarantees that child control will be suitable for (for instance) Grid cell with explicitly specified Width/Height. BUT because FrameworkElement.MeasureCore
remembers your "unclipped" DesiredSize
, in ArrangeOverride
you should receive a parameter = your original DesiredSize
. At result of it your control "virtually" arranges children according to its original DesiredSize
, but FrameworkElement
implementation will clip your control for such parent Grid cell. Concrete clipping manner will depend of actual values of properties like Horizontal/VerticalAlignment
(properties of your control).