Reputation: 1693
In my specific case I need to present a collection of objects and would like to make all instances of certain types right-aligned but not otherwise modify their display. I attempted to do that using a data template that included a content presenter like so:
<me:MyDisplay>
<me:MyDisplay.Resources>
<DataTemplate DataType="{x:Type foo:bar}">
<Border HorizontalAligment="Stretch">
<ContentPresenter Content="{Binding}" HorizontalAlignment="Right"/>
</Border>
</DataTemplate>
</me:MyDisplay.Resources>
</me:MyDisplay>
But this throws a StackOverflowException
.
Here is the xaml from a simple test app that attempts what I am trying to do:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Window.Resources>
<sys:Int32 x:Key="test">42</sys:Int32>
<DataTemplate DataType="{x:Type sys:Int32}">
<Border Background="Red"
Padding="10">
<TextBlock Text="{Binding}"
Foreground="Green" />
</Border>
</DataTemplate>
</Window.Resources>
<StackPanel>
<!-- uses default template -->
<ContentPresenter Content="{StaticResource test}" />
<Border>
<Border.Resources>
<DataTemplate DataType="{x:Type sys:Int32}">
<!-- Wrap default template in a blue border -->
<Border Background="Blue"
Padding="10">
<ContentPresenter Content="{Binding}"/>
</Border>
</DataTemplate>
</Border.Resources>
<!-- ...but it doesn't work. -->
<ContentPresenter Content="{StaticResource test}" />
</Border>
</StackPanel>
Is there a good way to pull this off?
Upvotes: 1
Views: 284
Reputation: 25201
You defined your DataTemplate
as an implicit data template (you didn't specify a key for it) which means it will automatically be used by any contained controls, including the ContentPresenter
inside it.
This causes the ContentPresenter
to reference the DataTemplate
which then references the ContentPresenter
in an endless loop, which causes the StackOverflowException
.
To fix this, you can simply give your DataTemplate
a key and use it:
<Border>
<Border.Resources>
<DataTemplate DataType="{x:Type sys:Int32}" x:Key="myDataTemplate">
<!-- Wrap default template in a blue border -->
<Border Background="Blue"
Padding="10">
<ContentPresenter Content="{Binding}"/>
</Border>
</DataTemplate>
</Border.Resources>
<ContentPresenter Content="{StaticResource test}"
ContentTemplate="{StaticResource myDataTemplate}" />
</Border>
Upvotes: 2