为ItemsControl.ItemContainerStyle指定ControlTemplate

Tra*_*man 21 wpf itemscontrol controltemplate itemcontainerstyle

以下类似于我想要完成的任务.但是,我得到了错误

PropertyDescriptor值无效.

在模板上Setter.我怀疑这是因为我没有指定TargetTypeStyle; 但是,我不知道容器的类型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>
Run Code Online (Sandbox Code Playgroud)

Qua*_*ter 40

您可以使用类型名称限定属性名称:

<Setter Property="Control.Template">
Run Code Online (Sandbox Code Playgroud)

ItemsControl的容器通常是ContentPresenter,但如果子项是UIElement,则它不会使用容器.在这种情况下,所有子项都是Controls,因此ItemContainerStyle将直接应用于它们.如果添加了UIElement以外的其他项,则该setter将在ContentPresenter上设置Control.Template属性,该属性将成功但不起作用.

实际上,听起来你想要的是将每个孩子包装在容器中,即使它们已经是UIElement.为此,您必须使用ItemsControl的子类.您可以使用像ListBox这样的现有类,或者您可以继承 ItemsControl并覆盖GetContainerForItemOverrideIsItemItsOwnContainerOverride以将项目包装在您自己的容器中.您可以将它们包装在ContentControl中,然后将其用作Style的TargetType.

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

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        // Even wrap other ContentControls
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

您还需要在ControlTemplate上设置TargetType,以便ContentPresenter将绑定到Content属性:

<ControlTemplate TargetType="ContentControl">
Run Code Online (Sandbox Code Playgroud)