In the MenuKiller Control, I need to configure a TreeView
to quite some extent: I want all nodes to have a certain custom ItemContainerStyle
.
First naive approach: The TreeView
will apply its ItemContainerStyle
to all nodes. Wrong! The TreeViewItem
s themselves are ItemControl
s, therefore having their own ItemContainerStyle
.
Second approach: Have the ItemContainerStyle
refer to itself using a DynamicResource
:
<Style x:Key="MKItemStyle" TargetType="{x:Type local:MenuKillerItem}"> <Setter Property="Template" Value="{StaticResource MenuKillerItemTemplate}"/> <Setter Property="ItemContainerStyle" Value="{DynamicResource MKItemStyle}"/> </Style>
Wrong again! This does not work. Frankly, I don’t know why, but I didn’t bother to debug it.
There are quite some articles on customizing TreeView
s the net, for example Josh Smith’s article “Custom TreeView Layout in WPF” at the CodeProject. There didn’t seem to be any such problem… So what’s the catch?
A Simple Solution?
So what is it all about? In the source code accompanying Josh’s article, we find the following declaration:
<!-- This Style redefines the ControlTemplate used by TreeViewItems and also provides a different itemspanel for their child items. --> <Style TargetType="TreeViewItem"> [...] </Style>
So this will simply apply the defined style to each and every item of the TargetType.
Done!.
There are some drawbacks, though: In a small application, this might be OK, but it may result in problems with larger applications or control libraries. One simple trick, of course, is to create a custom control which derives from the control you want, and apply a default style to this derived type (I currently do this for the MenuKillerItem
, which derives from TreeViewItem
).
Yet, this solution is not well-templateable either. Users of a control library might want to override the default template only for children of a specific control, which is not possible this way.
Of course, one can write a recursive method to apply the style, but I doubt this is the cleanest solution. Any better ideas?
Thankfully, using DynamicResource to apply the style recursively works in .net 4.