Trouble with custom WPF Panel-derived class
Posted
by chaiguy
on Stack Overflow
See other posts from Stack Overflow
or by chaiguy
Published on 2010-06-09T01:53:30Z
Indexed on
2010/06/09
8:12 UTC
Read the original article
Hit count: 289
I'm trying to write a custom Panel
class for WPF, by overriding MeasureOverride
and ArrangeOverride
but, while it's mostly working I'm experiencing one strange problem I can't explain.
In particular, after I call Arrange
on my child items in ArrangeOverride
after figuring out what their sizes should be, they aren't sizing to the size I give to them, and appear to be sizing to the size passed to their Measure
method inside MeasureOverride
.
Am I missing something in how this system is supposed to work? My understanding is that calling Measure
simply causes the child to evaluate its DesiredSize
based on the supplied availableSize, and shouldn't affect its actual final size.
Here is my full code (the Panel, btw, is intended to arrange children in the most space-efficient manner, giving less space to rows that don't need it and splitting remaining space up evenly among the rest--it currently only supports vertical orientation but I plan on adding horizontal once I get it working properly):
protected override Size MeasureOverride( Size availableSize ) {
foreach ( UIElement child in Children )
child.Measure( availableSize );
return availableSize;
}
protected override System.Windows.Size ArrangeOverride( System.Windows.Size finalSize ) {
double extraSpace = 0.0;
var sortedChildren = Children.Cast<UIElement>().OrderBy<UIElement, double>( new Func<UIElement, double>( delegate( UIElement child ) {
return child.DesiredSize.Height;
} ) );
double remainingSpace = finalSize.Height;
double normalSpace = 0.0;
int remainingChildren = Children.Count;
foreach ( UIElement child in sortedChildren ) {
normalSpace = remainingSpace / remainingChildren;
if ( child.DesiredSize.Height < normalSpace ) // if == there would be no point continuing as there would be no remaining space
remainingSpace -= child.DesiredSize.Height;
else {
remainingSpace = 0;
break;
}
remainingChildren--;
}
extraSpace = remainingSpace / Children.Count;
double offset = 0.0;
foreach ( UIElement child in Children ) {
//child.Measure( new Size( finalSize.Width, normalSpace ) );
double value = Math.Min( child.DesiredSize.Height, normalSpace ) + extraSpace;
child.Arrange( new Rect( 0, offset, finalSize.Width, value ) );
offset += value;
}
return finalSize;
}
© Stack Overflow or respective owner