0

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!

Community
  • 1
  • 1
Jonathan Perry
  • 2,953
  • 2
  • 44
  • 51
  • Could it be a binding issue instead of a style issue? Check your debug output window. – Wallstreet Programmer Nov 15 '11 at 13:49
  • Don't think so since my Width / Height bind correctly. I think that the Style in the DataTemplate.Resources is not accessible. The code only looks at the ItemsControl.ItemContainerStyle code... – Jonathan Perry Nov 15 '11 at 14:13

1 Answers1

1

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

Rachel
  • 130,264
  • 66
  • 304
  • 490