Ok, this is neat. This is the first time I’ve worked with layout panels and actually creating one of my own. Here’s the code:
class OverlapStackPanel : StackPanel
protected override Size ArrangeOverride(Size arrangeSize)
UIElementCollection children = this.InternalChildren;
int childrenResolved = 0;
foreach (UIElement child in children)
Rect targetRect = new Rect(40 * childrenResolved, 30, child.DesiredSize.Width, child.DesiredSize.Height);
child.RenderTransform = new RotateTransform(-20);
Now, let’s look at it. First off, I could have inherited from Panel instead of StackPanel, and to be honest, I’m not sure how much of a change that would produce (I’ll have to experiment with that).
The only method I’m introducing is modifying the ArrangeOverride. This is telling the Panel that instead of using the built in Arranger, I’m going to specify my own.
It’s easy to see that I got the list of children, and all I did was create a Rect and in that, calculate where the child should go. I’m moving it over by childrenResolved * 40, so the first child is at X=0, then next at 40, then 80, etc… I moved it down by 30 to be arbitrary, and then used the child’s desired size to get the width and height.
Adding the RotateTransform is just for fun, but it does cause problems, since it’s effectively overwriting ANY RenderTransform that the user might apply. To do this correctly, I should probably get the existing RenderTransform, and add the desired rotation and all of that, but here, my goal is to demonstrate the simplicity.
The two lines that you can’t forget… you need to call child.Arrange and pass the rectangle, otherwise, the child just ends up in Oblivion. And, if you don’t return the arrangeSize, I’m sure it will do something funky. Again, something else I haven’t experimented with yet.
To be honest, I’ve surprised myself with how easy this was to do. With some math, it wouldn’t be too hard to create a layout that takes the controls and fans them out in a way that looks like a hand of cards or something.