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?
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.
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.