tags:

views:

69

answers:

2

Hi, I have a Panel which I want to extend and override MeassureOverride and Arrange to have my custom layout. Basically, the panel will contain some labels. As the label has some text content, it should have a specific size. However when I use label.ActualHeight or actualwidth, desiredSize ... in the MeassureOverride or ArrangeOverride, all result to NaN. Is there any way I can get the desired Size of the label so that the text content is fit?

+2  A: 

The DesiredSize for each child is only set after you have measured it. In your MeasureOverride you must call child.Measure() for every of your panel's children. The same goes with child.Arrange() in ArrangeOverride.

See http://msdn.microsoft.com/en-us/library/ms745058.aspx#LayoutSystem_Measure_Arrange

Edit in response to your comment: just pass the maximum size your label could have (the available size), or a constrained size if you need to. The label once measured will use its minimum size as the DesiredSize if the alignments are different from stretch.

Julien Lebosquain
Hi Julien. Thanks for your help. As I understand, the MeasureOverride method is for the child Elements to tell it parent how much space it needs. But if I can't get its DesiredSize before Measure, how can I tell how much width n height the Panel need to accommodate its text content? In other words, what's should I return in each measure call if not the DesiredSize of the Label?
Khue Vu
+2  A: 

Do you call base.MeasureOverride(abailableSize) and base.ArrangeOverride(finalSize) at the end of each method?

Here is an example of creating a custom panel

A custom implementation of MeasureOverride might look like this (from the post):

protected override Size MeasureOverride(Size availableSize)
{
    Size sizeSoFar = new Size(0, 0);
    double maxWidth = 0.0;

    foreach (UIElement child in Children)
    {
        child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

        if (sizeSoFar.Width + child.DesiredSize.Width > availableSize.Width)
        {
            sizeSoFar.Height += child.DesiredSize.Height;
            sizeSoFar.Width = 0;
        }
        else
        {
            sizeSoFar.Width += child.DesiredSize.Width;
            maxWidth = Math.Max(sizeSoFar.Width, maxWidth);
        }
    }

    return new Size(maxWidth, sizeSoFar.Height);
}

A custom implementation of ArrangeOverride might look like this (from the post):

protected override Size ArrangeOverride(Size finalSize)
{
    Size sizeSoFar = new Size(0, 0);

    foreach (UIElement child in Children)
    {
        child.Arrange(new Rect(sizeSoFar.Width, sizeSoFar.Height, 
                               child.DesiredSize.Width, child.DesiredSize.Height));

        if (sizeSoFar.Width + child.DesiredSize.Width >= finalSize.Width)
        {
            sizeSoFar.Height += child.DesiredSize.Height;
            sizeSoFar.Width = 0;
        }
        else
        {
            sizeSoFar.Width += child.DesiredSize.Width;
        }
    }

    return finalSize;
}

If you want to force the panel rendering (call the MeasureOverride function), use the InvalidateMeasure function

You could also check out Custom Panel Elements on msdn.

SwDevMan81
Hi DevMan, thanks for your answer. I didn't use the base methods. I My DesiredSize is NaN is it because the Panel is contained inside a Grid, which I set its Size to Auto ?? (however, i have set the MinHeight, MinWidth Property as well)
Khue Vu
Hi, I tried this and it works
Khue Vu