I ran into the same odd/tricky problem as you're describing above, and ran into a blog post that suggested a neat little hack/fix which seems to provide the behaviour you're after. The main points are repeated in case the link dies.
You've already described the odd requirements for ListView
styling if you want to cover views with and that make use of GridViews
; a basic ListView
needs a ContentPresenter
, a GridView ListView needs
a GridViewRowPresenter
.
The poster managed to get around this by including both presenters within his style, and using a Setter
to show the ContentPresenter
only when required.
So your ControlTemplate
could implement something along these lines (with your extra styling properties added as required):
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<!-- Pair of presenters -->
<Grid>
<GridViewRowPresenter x:Name="gridrowPresenter"
Content="{TemplateBinding Property=ContentControl.Content}"/>
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Property=ContentControl.Content}" Visibility="Collapsed"/>
</Grid>
<!-- Visibility Controlling Setter -->
<ControlTemplate.Triggers>
<Trigger Property="GridView.ColumnCollection" Value="{x:Null}">
<Setter TargetName="contentPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Both GridViewRowPresenter
and ContentPresenter
are present in the style, but the ContentPresenter
is hidden (Visibility="Collapsed"
).
The neat trick is the use of a Trigger
on GridView.ColumnCollection
; if this value is null (which occurs when the GridViewRowPresenter
has no content), the ContentPresenter
will be made visible, correctly displaying your normal ListView
content). The GridViewRowPresenter
will have no content, so it won't display any conflicting visuals.
If the GridView
has content, it will be displayed (providing the correct row formatting), and the ContentPresenter
will remain hidden.
Original blog entry: http://www.steelyeyedview.com/2010/03/contentpresenter-gridviewrowpresenter.html