Sometimes you want to tweak the layout of a particular panel without having to subclass the control. You can attach new behaviors to existing panels by using Attached Properties that modify the layout of the children before the children are rendered to the screen. Dan Crevier uses such a technique in his PanelLayoutAnimator where he adds an animation to the children of the panel by using a private attached property to attach the updater class to the original panel setting the attached property.
Here I use the same techique to solve a different problem.
Recently someone in the MSDN WPF forums asked how to display items in a WrapPanel to be aligned to the right when the items are wrapped.
The developer provided this code to illustrate the problem:
As you can see, the wrapped items are still aligned to the left. The simple solution to this problem is to change the flow direction of the panel like this:
which now produces this output:

This is indeed the desired behavour albeit with one glaring caveat. The items are displayed in reversed order! The green box, which was at the end of the items, is now first. If you’re adding the items in a code-behind you have two options, do an insert at index 0 to push items to the front of the collection so they display correctly or reverse your collection before adding it or binding it to the panel.
This is a horrible idea fraught with risky refactoring of collection population and binding code throughout your code to accomplish something that is a UI layout problem.
Although a XAML only solution would be nice, in this case we have to write code to solve the ordering problem. One solution would be to subclass WrapPanel and override it’s Arrange method. This is a perfectly valid solution.
Let’s say however that your design team is a picky bunch and they don’t want to have to go updating opening and closing tags all over the place where wrap panels are used to change it to your new control. Let’s say they insist this new functionality be able to be added to their existing WrapPanels by setting a property on the existing XAML elements.
Well then, now we’re primed to use an attached property to accomplish what we need.
The solution requires a class that exposes an attached property to allow a designer to enable or disable our behavour in XAML. The default of the property is to be set to false which disables our layout tweak. In addition, the class should have a private attached property which we’ll use to attach an instance of our class to the wrap panel setting the property. Don’t get lost yet, I’ll explain in code further in the post. The last requirement is that our class accept a parameter in its constructor of type WrapPanel which ensures our attached property is limited to working on WrapPanels and allows us to subscribe to the WrapPanel’s layout updated event which occurs after all the children have been laid out but before they’re rendered. This gives us the opportunity to modify them a bit before they get rendered to the screen.
Here’s the portion of our class built to manipulate the children. It’s pretty straightfword:
As you can see, in our constructor we receive our wrap panel and subscribe to it’s LayoutUpdated event. In the LayoutUpdated eventhandler we first reverse the order of our children, then calculate locations and arrange them. Finally we provide a detach method to unsubscribe to the wrap panel’s event and clean up.
Now the question is, how do we receive the wrap panel we manipulate?
With the following attached property added to the class definition:
The interesting bit here is in our handling of the OnIsEnabledChanged event. We receive the WrapPanel that set the static property, if it’s set to true, we create a new instance of the class hosting the property passing in the source WrapPanel into the constructer.
Then we use a private attached property defined in the same class:
…to store our new class instance as an attached property to our source WrapPanel. When the IsEnabled attached property is set to False, we retrieve our class instance from the private attached property and call the Detach method to unsubscribe to the LayoutUpdated event, thus preventing further layout tweaks.
With this in place we can now use the property like so:
…after we declare the “local” namespace pointing to our assembly. This now produces the following desired output:

So now you have a method to use an attached property to modify existing elements without having to subclass the element. This would be even more valuable in cases where we want to attach behavior to any panel type, not just wrap panels.
Source code here.
Have a nice day.
