为ItemsControl.ItemContainerStyle指定ControlTemplate

以下类似于我想要完成的任务。但是,我得到了错误   PropertyDescriptor值无效。 在模板
Setter
。我怀疑是因为我没有为
Style
指定
TargetType
;但是,我不知道
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>
    
已邀请:
您可以使用类型名称限定属性名称:
<Setter Property="Control.Template">
ItemsControl的容器通常是ContentPresenter,但如果子项是UIElement,则它不会使用容器。在这种情况下,所有子项都是Controls,因此ItemContainerStyle将直接应用于它们。如果添加了UIElement之外的其他项,则该setter将在ContentPresenter上设置Control.Template属性,该属性将成功但不起作用。 实际上,听起来你想要的是将每个孩子包装在容器中,即使它们已经是UIElement。为此,您必须使用ItemsControl的子类。您可以使用像ListBox这样的现有类,或者您可以继承ItemsControl并覆盖GetContainerForItemOverride和IsItemItsOwnContainerOverride以将项目包装在您自己的容器中。您可以将它们包装在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;
    }
}
您还需要在ControlTemplate上设置TargetType,以便ContentPresenter将绑定到Content属性:
<ControlTemplate TargetType="ContentControl">
    
此外,如果您只想使用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">
然后我们为ListBoxItem创建一个新的ControlTemplate。请注意,ContentPresenter未被使用,因为它总是出现在文章和教程中,您需要将其模板绑定到ListBoxItem的Content属性,因此它将显示该项目的内容。
<ContentPresenter Content="{TemplateBinding Content}" />
我只是遇到了同样的问题并以这种方式修复了它。我不想要ListBox(项目选择)的一些功能,并且通过使用这种技术,项目选择不再起作用。     

要回复问题请先登录注册