Применение разных стилей к ItemsControl

Я использую CompositeCollection для размещения объектов, которые хочу отобразить в элементе управления ItemsControl, я использовал это решение для реализации с использованием разных шаблонов данных для разных объектов, однако я хочу применить для каждого из типов в моей коллекции другой стиль. Как я могу это сделать?

Это мой код:

<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>

Фактический результат выполнения этого заключается в том, что объекты MapObjects будут отображаться в правильном месте на Canvas, но объект ReferenceMapRectangle останется фиксированным в (0,0) на холсте и никогда не будет перемещаться (ширина / высота обновляются, хотя )

Кто-нибудь знает, почему это могло произойти? Я пробовал использовать ItemsControl.ItemContainerStyle, но он поддерживает только один стиль, а не несколько стилей.

Спасибо!


person Jonathan Perry    schedule 15.11.2011    source источник
comment
Может быть, это проблема привязки, а не проблема стиля? Проверьте окно вывода отладки.   -  person Wallstreet Programmer    schedule 15.11.2011
comment
Не думайте, так как мои ширина / высота привязываются правильно. Я думаю, что Style в DataTemplate.Resources недоступен. Код смотрит только на код ItemsControl.ItemContainerStyle ...   -  person Jonathan Perry    schedule 15.11.2011


Ответы (1)


Каждый элемент в ItemsControl заключен в тег <ContentPresenter>, поэтому применение вашего позиционирования к фактическому элементу данных ничего не даст.

Вы можете использовать ItemContainerStyle, чтобы применить позиционирование к тегу ContentPresenter вместо тега DataItem.

Например, вот как визуализируются ваши элементы управления, если вы применяете позиционирование к вашему 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>

А вот как будут отображаться ваши элементы управления, если вы примените позиционирование в 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>

См. Еще один пример в этой моей записи в блоге.

person Rachel    schedule 15.11.2011