[英]Specify ControlTemplate for ItemsControl.ItemContainerStyle
The following is similar to what I'm trying to accomplish. 以下类似于我想要完成的任务。 However, I get the error
但是,我得到了错误
Invalid PropertyDescriptor value.
PropertyDescriptor值无效。
on the Template Setter
. 在模板
Setter
。 I suspect it's because I didn't specify a TargetType
for the Style
; 我怀疑是因为我没有为
Style
指定TargetType
; however, I don't know the container type for ItemsControl
. 但是,我不知道
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>
You can qualify the property name with the type name: 您可以使用类型名称限定属性名称:
<Setter Property="Control.Template">
The container for ItemsControl
is normally a ContentPresenter
, but if the child is a UIElement
then it won't use a container. ItemsControl
的容器通常是ContentPresenter
,但如果子项是UIElement
则它不会使用容器。 In this case, all of the children are Controls, so the ItemContainerStyle
will apply to them directly. 在这种情况下,所有子项都是Controls,因此
ItemContainerStyle
将直接应用于它们。 If you added an item other than a UIElement
, that setter would set the Control.Template
property on the ContentPresenter
, which would succeed but have no effect. 如果添加了
UIElement
之外的其他项,则该setter将在ContentPresenter
上设置Control.Template
属性,该属性将成功但不起作用。
Actually, it sounds like what you want is to wrap each child in a container, even if they are already a UIElement
. 实际上,听起来你想要的是将每个孩子包装在容器中,即使它们已经是
UIElement
。 To do that, you will have to use a subclass of ItemsControl
. 为此,您必须使用
ItemsControl
的子类。 You could use an existing one like ListBox
, or you could subclass ItemsControl
and override GetContainerForItemOverride
and IsItemItsOwnContainerOverride
to wrap the items in your own container. 您可以使用像
ListBox
这样的现有类,或者您可以IsItemItsOwnContainerOverride
ItemsControl
并覆盖GetContainerForItemOverride
和IsItemItsOwnContainerOverride
以将项目包装在您自己的容器中。 You could wrap them in a ContentControl
and then use that as the TargetType
for the Style
. 您可以将它们包装在
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;
}
}
You will also need to set the TargetType
on the ControlTemplate
so that the ContentPresenter
will bind to the Content
property: 您还需要在
ControlTemplate
上设置TargetType
,以便ContentPresenter
将绑定到Content
属性:
<ControlTemplate TargetType="ContentControl">
Also if you only want to do all of it with XAML you can simply use ListBox instead of ItemsControl and define a style for ListBoxItem: 此外,如果您只想使用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>
Note that because I am using ListBox the container is ListBoxItem(Generally the container for WPF's default list control is always named the Item) so we create a style for ListBoxItem: 请注意,因为我使用的是ListBox,所以容器是ListBoxItem(通常WPF默认列表控件的容器总是命名为Item)所以我们为ListBoxItem创建一个样式:
<Style TargetType="ListBoxItem">
Then we create a new ControlTemplate for ListBoxItem. 然后我们为ListBoxItem创建一个新的ControlTemplate。 Please note that ContentPresenter is not used as it always appears in articles and tutorials, you need to template-bind it to Content property of ListBoxItem, so it will show the content for that item.
请注意,ContentPresenter未被使用,因为它总是出现在文章和教程中,您需要将其模板绑定到ListBoxItem的Content属性,因此它将显示该项目的内容。
<ContentPresenter Content="{TemplateBinding Content}" />
I just had the same problem and fixed it this way. 我只是遇到了同样的问题并以这种方式修复了它。 I dont wanted some functionalities of ListBox ( item selection ) and by using this technique the item selection does not work anymore.
我不想要ListBox(项目选择)的一些功能,并且通过使用这种技术,项目选择不再起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.