I have a UserControl looking like this:
<UserControl
MaxHeight="32"
MaxWidth="32"
MinHeight="25"
MinWidth="25">
<DockPanel>
<!-- some stuff -->
</DockPanel>
</UserControl>
In addition to the min/max size constraint, I want the control always being painted with Width = Height
. So i override Me开发者_高级运维asureOverride
and ArrangeOverride
:
protected override Size MeasureOverride(Size availableSize)
{
var resultSize = new Size(0, 0);
((UIElement)Content).Measure(availableSize);
var sideLength = Math.Min(((UIElement)Content).DesiredSize.Width, ((UIElement)Content).DesiredSize.Height);
resultSize.Width = sideLength;
resultSize.Height = sideLength;
return resultSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
((UIElement)Content).Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
return finalSize;
}
I understand that I must call Measure
and Arrange
on every child of the UserControl. Since the DocPanel is the only child of my UserControl and (in my understanding) is stored in the Content
property of the UserControl, I simply call Measure
and Arrange
on this Content property. However the UserControl is not displayed. What am I doing wrong?
Depending on how you are hosting your UserControl, the value returned from the Measure phase may not be used. If you have it setup in a Grid with star rows/columns or a DockPanel, then the final size may be completely different.
You would need to apply similar logic to the arrange phase, so it will effectively ignore any extra space it's given.
The following code should work, and is a bit cleaner:
protected override Size MeasureOverride(Size availableSize) {
var desiredSize = base.MeasureOverride(availableSize);
var sideLength = Math.Min(desiredSize.Width, desiredSize.Height);
desiredSize.Width = sideLength;
desiredSize.Height = sideLength;
return desiredSize;
}
protected override Size ArrangeOverride(Size finalSize) {
var sideLength = Math.Min(this.DesiredSize.Width, this.DesiredSize.Height);
return base.ArrangeOverride(new Size(sideLength, sideLength));
}
精彩评论