Подтвердить что ты не робот

Укажите ControlTemplate для ItemsControl.ItemContainerStyle

Следующее похоже на то, что я пытаюсь выполнить. Однако я получаю сообщение об ошибке

Недопустимое значение PropertyDescriptor.

на шаблоне Setter. Я подозреваю это, потому что я не указал <<21 > для Style; однако я не знаю тип контейнера для ItemsControl.

<ItemsControl>
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <StackPanel>
                            <TextBlock Text="Some Content Here" />
                            <ContentPresenter />
                            <Button Content="Edit" />
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <!-- heterogenous controls -->
    <ItemsControl.Items> 
        <Button Content="Content 1" />
        <TextBox Text="Content 2" />
        <Label Content="Content 3" />
    </ItemsControl.Items>
</ItemsControl>
4b9b3361

Ответ 1

Вы можете указать имя свойства с именем типа:

<Setter Property="Control.Template">

Контейнер для ItemsControl обычно является ContentPresenter, но если дочерний элемент является UIElement он не будет использовать контейнер. В этом случае все дочерние элементы являются ItemContainerStyle управления, поэтому ItemContainerStyle будет применяться к ним напрямую. Если вы добавите элемент, отличный от UIElement, этот установщик установит свойство Control.Template для ContentPresenter, что будет успешно выполнено, но не будет иметь никакого эффекта.

На самом деле, звучит так, как будто вы хотите заключить каждого дочернего элемента в контейнер, даже если он уже является UIElement. Для этого вам нужно будет использовать подкласс ItemsControl. Вы можете использовать существующий, например ListBox, или GetContainerForItemOverride подкласс ItemsControl и переопределить GetContainerForItemOverride и IsItemItsOwnContainerOverride чтобы обернуть элементы в вашем собственном контейнере. Вы можете обернуть их в ContentControl а затем использовать его в качестве TargetType для Style.

public class CustomItemsControl
    : ItemsControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new ContentControl();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        // Even wrap other ContentControls
        return false;
    }
}

Вам также нужно будет установить TargetType на ControlTemplate чтобы ContentPresenter связывался со свойством Content:

<ControlTemplate TargetType="ContentControl">

Ответ 2

Также, если вы хотите использовать все это только с помощью XAML, вы можете просто использовать ListBox вместо ItemsControl и определить стиль для ListBoxItem:

        <ListBox ItemsSource="{Binding Elements.ListViewModels}">
        <ListBox.Resources>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <StackPanel>
                                <TextBlock>Some Content Here</TextBlock>
                                <ContentPresenter Content="{TemplateBinding Content}" />
                                <Button>Edit</Button>
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.Resources>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>

Обратите внимание, что поскольку я использую ListBox, контейнер является ListBoxItem (обычно контейнер для элемента управления списком по умолчанию WPF всегда называется Item), поэтому мы создаем стиль для ListBoxItem:

<Style TargetType="ListBoxItem">

Затем мы создаем новый элемент ControlTemplate для ListBoxItem. Обратите внимание, что ContentPresenter не используется, поскольку он всегда появляется в статьях и учебниках, вам необходимо привязать шаблон к свойству Content свойства ListBoxItem, чтобы он отображал содержимое для этого элемента.

<ContentPresenter Content="{TemplateBinding Content}" />

У меня была такая же проблема, и я исправил ее таким образом. Мне не нужны некоторые функции ListBox (выбор элементов), и с помощью этой техники выбор элемента больше не работает.