Оберните что-нибудь вокруг каждого элемента в ItemsControl

Скажем, у меня есть коллекция объектов разных классов. Каждый класс имеет свой UserControl DataTemplated в файле ресурсов.

Теперь я хочу использовать ItemsControl для отображения коллекции, но я хочу, чтобы вокруг каждого элемента была граница или расширитель.

Я бы ожидал чего-то подобного:

<ItemsControl ItemsSource="{Binding MyObjects}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="3">
                <ContentPresenter/>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Но ContentPresenter, кажется, выбирает ItemTemplate, потому что я получаю переполнение стека.

Как получить каждый элемент DataTemplate внутри ItemTemplate?

Ответ 1

Обычно вы можете это сделать, создавая шаблоны контейнера элементов. Проблема заключается в том, что "общий" ItemsControl использует ContentPresenter в качестве контейнера своего элемента. Поэтому даже если вы попытаетесь установить стиль с помощью ItemContainerStyle, вы обнаружите, что не можете предоставить шаблон, потому что ContentPresenter не поддерживает шаблонизацию управления (он поддерживает шаблоны данных, но здесь не используется).

Чтобы использовать шаблонный контейнер, вам придется отвлечься от ItemsControl, как в этом .

Альтернативой может быть просто использование управления ListBox. Затем вы можете просто создать собственный шаблон, установив шаблон ListBoxItem с помощью стиля.

Подробнее о контейнерах здесь.

(С вашим permissen я добавляю решение к вашему ответу, Guge)

    <ListBox ItemsSource="{Binding MyObjects}" Grid.Column="1">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border BorderBrush="Black" BorderThickness="3">
                                <ContentPresenter/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>