以下は、私が達成しようとしていることに似ています。しかし、私はエラーが出ます
無効なPropertyDescriptor値。
テンプレートSetter
。 TargetType
にStyle
を指定しなかったためだと思います。ただし、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
の場合はコンテナーを使用しません。この場合、すべての子はコントロールであるため、ItemContainerStyle
が直接適用されます。 UIElement
以外のアイテムを追加した場合、そのセッターはControl.Template
プロパティはContentPresenter
で成功しますが、効果はありません。
実際には、子がすでに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;
}
}
また、TargetType
がControlTemplate
プロパティにバインドされるように、ContentPresenter
にContent
を設定する必要があります。
<ControlTemplate TargetType="ContentControl">
また、すべてをXAMLで行うだけの場合は、ItemsControlの代わりにListBoxを使用して、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(アイテム選択)の一部の機能が欲しくなかったので、この手法を使用すると、アイテム選択が機能しなくなります。