I'm working on a custom WPF Panel that works similar to a Canvas except that the placements of its children are expressed as percentages instead of absolute offsets. The Panel, which I'm calling PercentageCanvas would be used like so:
<Window>
<local:PercentageCanvas>
<ChildElement local:PercentageCanvas.Left=".30" local:PercentageCanvas.Top=".50" />
<ChildElement local:PercentageCanvas.Left="0" local:PercentageCanvas.Top=".9" />
... etc ...
</local:PercentageCanvas>
</Window>
I have the PercentageCanvas working, although not quite as I expected. The children of the PercentageCanvas are positioned relative to the center of the child, rather than the top-left edge, as I had expected. Here's the ArrangeOverride method I use that gives me this behavior:
protected override Size ArrangeOverride(Size finalSize)
{
int currentIndex = 0;
for (int index = InternalChildren.Count - 1; index >= 0; index--)
{
Rect rect = new Rect(finalSize);
rect.Location = new Point()
{
X = finalSize.Width * PercentagePanel.GetLeft(InternalChildren[index]) - finalSize.Width / 2,
Y = finalSize.Height * PercentagePanel.GetTop(InternalChildren[index]) - finalSize.Height / 2
};
InternalChildren[index].Arrange(rect);
currentIndex++;
}
return finalSize;
}
It seems that to counteract this center-positioning behavior, I'll need to know each child's dimensions and compensate for the child's size while computing the Location of the Rect. However, I don't seem to have access to the child's size in order to compute the appropriate offset.
How can I take into account the size of a Panel's child while computing the child's layout in the ArrangeOverride method?
Found the answer while in the middle of writing up the question. All
UIElementshave aDesiredSizeproperty which gives me exactly what I'm looking for. MyArrangeOverridemethod now looks like this (you'll have to scroll to the right to see the difference):The elements now position themselves relative to their top-left corner instead of their center.