wpf - Especifique ControlTemplate para ItemsControl.ItemContainerStyle
(2)
Además, si solo desea hacerlo todo con XAML, simplemente puede usar ListBox en lugar de ItemsControl y definir un estilo para 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>
Tenga en cuenta que debido a que estoy usando ListBox, el contenedor es ListBoxItem (generalmente, el contenedor para el control de lista predeterminado de WPF siempre recibe el nombre de Artículo), por lo que creamos un estilo para ListBoxItem:
<Style TargetType="ListBoxItem">
Luego creamos una nueva plantilla ControlTemplate para ListBoxItem. Tenga en cuenta que ContentPresenter no se usa como siempre aparece en los artículos y tutoriales, debe enlazarlo con la plantilla a la propiedad Contenido de ListBoxItem, para que muestre el contenido de ese elemento.
<ContentPresenter Content="{TemplateBinding Content}" />
Acabo de tener el mismo problema y lo arreglé de esta manera. No quería algunas funcionalidades de ListBox (selección de elementos) y al utilizar esta técnica, la selección de elementos ya no funciona.
Lo siguiente es similar a lo que estoy tratando de lograr. Sin embargo, me sale el error
Valor de PropertyDescriptor no válido.
en la plantilla Setter
. Sospecho que es porque no especifiqué un TargetType
para el Style
; sin embargo, no conozco el tipo de contenedor para 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>
Puede calificar el nombre de la propiedad con el nombre de tipo:
<Setter Property="Control.Template">
El contenedor para ItemsControl normalmente es un ContentPresenter, pero si el hijo es un UIElement, entonces no utilizará un contenedor. En este caso, todos los elementos secundarios son Controles, por lo que el ItemContainerStyle se aplicará directamente a ellos. Si agregó un elemento que no sea un UIElement, esa persona establecería la propiedad Control.Template en el ContentPresenter, que tendría éxito pero no tendría efecto.
En realidad, parece que lo que quieres es envolver a cada niño en un contenedor, incluso si ya son un UIElement. Para hacer eso, tendrá que usar una subclase de ItemsControl. Puede usar uno existente como ListBox, o puede crear una subclase de ItemsControl y anular GetContainerForItemOverride e IsItemItsOwnContainerOverride para envolver los elementos en su propio contenedor. Podría envolverlos en un ContentControl y luego usarlo como TargetType para el estilo.
public class CustomItemsControl
: ItemsControl
{
protected override DependencyObject GetContainerForItemOverride()
{
return new ContentControl();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
// Even wrap other ContentControls
return false;
}
}
También deberá establecer TargetType en la plantilla ControlTemplate para que ContentPresenter se vincule a la propiedad Content:
<ControlTemplate TargetType="ContentControl">