tags:

views:

225

answers:

1

I'm trying to build a simple panel that contains one child and will snap it to nearest grid sizes. I'm having a hard time figuring out how to do this by overriding MeasureOverride and ArrangeOverride.

Here's what I'm after: I want my panel to tell its owner that (a) it wants to be as large as possible, then (b) when it finds out what that size is, it will size itself and its child UIElement according to the nearest smaller snap point. So if we're snapping to 10's, and I can be in a region no bigger than 192x184, the panel will tell its parent container "my actual size is going to be 190x180". That way anything bordering my control will be able to align to its edges, as opposed to the potential space.

When I put my panel inside of a Grid, I get either 0 or PositiveInfinity (I forget) for the incoming size in the overrides, but what I need to know is "how big can my space actually get?" not infinities..

Part of the problem I think is what WPF considers magic values of PositiveInfinity and 0 for size. I need a way to say, via MeasureOverride "I can be as big as you will allow me" and in ArrangeOverride to actually size to the snapped size.

Or am I going about this the completely wrong way? Measuring and arranging looks very complicated, just from wandering around a little in the code for the standard panels in Reflector.

A: 

In the measure step, if WPF sends you infinity, you are supposed to tell it how big you want to be. If it sends 0, then there is literally no space for your layout. In the arrange step, you will be told how much space is available for layout, which is very likely to be different than the size you were given in the measure step. You can not return infinity in either step. The following code should accomplish what you are after (note that I am assuming a UIElement Child property):

protected overrride Size MeasureOverride(Size availableSize)
{
    Child.Measure(availableSize);
    return Child.DesiredSize;
}

protected override Size ArrangeOverride(Size finalSize)
{
    int w = (((int)finalSize.Width) / SnapPrecision) * SnapPrecision;
    int h = (((int)finalSize.Height) / SnapPrecision) * SnapPrecision;

    Child.Arrange(new Rect(0, 0, w, h));
    return new Size(w, h);
}
Abe Heidebrecht