Reputation: 3053
I'm using a CompositeCollection
to host objects I want to display in a ItemsControl
control, I used this solution to implement using different DataTemplates for the different objects, however I want to apply for each of the types in my collection a different style. How can I do this?
This is my code:
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type mapNamespace:MapObject}">
<DataTemplate.Resources>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding MapObjLocation.X}" />
<Setter Property="Canvas.Top" Value="{Binding MapObjLocation.Y}" />
</Style>
</DataTemplate.Resources>
<Rectangle Fill="#00000000" Height="10" Width="10" Stroke="Red">
<Rectangle.ToolTip>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="X: "/>
<TextBlock Text="{Binding MapObjLocation.X}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Y: " />
<TextBlock Text="{Binding MapObjLocation.Y}" />
</StackPanel>
</StackPanel>
</Rectangle.ToolTip>
</Rectangle>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:ReferenceMapRectangle}">
<DataTemplate.Resources>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</DataTemplate.Resources>
<Rectangle Height="{Binding Height, Mode=TwoWay}" Width="{Binding Width, Mode=TwoWay}" Stroke="White" StrokeThickness="6"
Canvas.Top="{Binding Y, Mode=TwoWay}" Canvas.Left="{Binding X, Mode=TwoWay}" >
</Rectangle>
</DataTemplate>
</ItemsControl.Resources>
The actual result from running this is that the MapObjects will be shown in the correct location on the Canvas
, but the ReferenceMapRectangle
object will stay fixed in (0,0) on the canvas and will never move (the width / height does update, though)
Does anyone have a clue why this could happen? I tried using ItemsControl.ItemContainerStyle
but it only supports one style, and not multiple styles.
Thanks!
Upvotes: 0
Views: 1178
Reputation: 132558
Each Item in an ItemsControl
is wrapped in a <ContentPresenter>
tag, so applying your positioning on your actual DataItem will do nothing.
You can use ItemContainerStyle
to apply the positioning on the ContentPresenter
tag instead of your DataItem tag
For example, here is how your controls get rendered if you apply positioning to your DataItem
:
<Canvas>
<ContentPresenter>
<DataItem Canvas.Left="50" Canvas.Top="50" />
</ContentPresenter>
<ContentPresenter>
<DataItem Canvas.Left="100" Canvas.Top="50" />
</ContentPresenter>
<ContentPresenter>
<DataItem Canvas.Left="150" Canvas.Top="50" />
</ContentPresenter>
</Canvas>
And here is how your controls would get rendered if you apply positioning in the ItemContainerStyle
:
<Canvas>
<ContentPresenter Canvas.Left="50" Canvas.Top="50">
<DataItem />
</ContentPresenter>
<ContentPresenter Canvas.Left="100" Canvas.Top="50">
<DataItem />
</ContentPresenter>
<ContentPresenter Canvas.Left="150" Canvas.Top="50">
<DataItem />
</ContentPresenter>
</Canvas>
See this blog entry of mine for another example
Upvotes: 1