wpf 为 ItemsControl.ItemContainerStyle 指定 ControlTemplate
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3542381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Specify ControlTemplate for ItemsControl.ItemContainerStyle
提问by Travis Heseman
The following is similar to what I'm trying to accomplish. However, I get the error
以下内容与我正在尝试完成的内容类似。但是,我收到错误
Invalid PropertyDescriptor value.
无效的 PropertyDescriptor 值。
on the Template Setter
. I suspect it's because I didn't specify a TargetType
for the Style
; however, I don't know the container type for ItemsControl
.
在模板上Setter
。我怀疑这是因为我没有TargetType
为Style
;指定 a 但是,我不知道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>
回答by Quartermeister
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. In this case, all of the children are Controls, so the ItemContainerStyle
will apply to them directly. 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.
for 的容器ItemsControl
通常是 a ContentPresenter
,但如果孩子是 aUIElement
则它不会使用容器。在这种情况下,所有子项都是 Controls,因此ItemContainerStyle
将直接应用于它们。如果您添加了 a 以外的项目UIElement
,则该 setter 将在Control.Template
上设置该属性ContentPresenter
,这会成功但无效。
Actually, it sounds like what you want is to wrap each child in a container, even if they are already a UIElement
. To do that, you will have to use a subclass of 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. You could wrap them in a ContentControl
and then use that as the TargetType
for the Style
.
实际上,听起来您想要的是将每个孩子包装在一个容器中,即使它们已经是UIElement
. 为此,您必须使用ItemsControl
. 您可以使用现有的,例如ListBox
,或者您可以子类化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;
}
}
You will also need to set the TargetType
on the ControlTemplate
so that the ContentPresenter
will bind to the Content
property:
您还需要设置TargetType
onControlTemplate
以便ContentPresenter
将绑定到Content
属性:
<ControlTemplate TargetType="ContentControl">
回答by 000
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. 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.
然后我们为 ListBoxItem 创建一个新的 ControlTemplate。请注意 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(项目选择)的某些功能,通过使用这种技术,项目选择不再起作用。