web-dev-qa-db-ja.com

ItemsControl.ItemContainerStyleのControlTemplateを指定します

以下は、私が達成しようとしていることに似ています。しかし、私はエラーが出ます

無効なPropertyDescriptor値。

テンプレートSetterTargetTypeStyleを指定しなかったためだと思います。ただし、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>
21
Travis Heseman

プロパティ名はタイプ名で修飾できます。

<Setter Property="Control.Template">

ItemsControlのコンテナーは通常ContentPresenterですが、子がUIElementの場合はコンテナーを使用しません。この場合、すべての子はコントロールであるため、ItemContainerStyleが直接適用されます。 UIElement以外のアイテムを追加した場合、そのセッターはControl.TemplateプロパティはContentPresenterで成功しますが、効果はありません。

実際には、子がすでにUIElementである場合でも、コンテナーで各子をラップするのが望ましいようです。そのためには、ItemsControlのサブクラスを使用する必要があります。 ListBoxのような既存のものを使用するか、ItemsControlをサブクラス化して GetContainerForItemOverrideIsItemItsOwnContainerOverrideをオーバーライドすることができます。 自分のコンテナでアイテムをラップします。それらをContentControlでラップし、TargetTypeStyleとして使用できます。

public class CustomItemsControl
    : ItemsControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new ContentControl();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        // Even wrap other ContentControls
        return false;
    }
}

また、TargetTypeControlTemplateプロパティにバインドされるように、ContentPresenterContentを設定する必要があります。

<ControlTemplate TargetType="ContentControl">
40
Quartermeister

また、すべてを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(アイテム選択)の一部の機能が欲しくなかったので、この手法を使用すると、アイテム選択が機能しなくなります。

3
000