選択されている場合、ListBox項目のWPF DataTemplateを変更します


89

項目が選択されているかどうかに応じて、ListBox内の項目のDataTemplateを変更する必要があります(選択すると、異なる/詳細情報を表示します)。

問題のリストボックスアイテムをクリックすると(タブ操作でのみ)、DataTemplate(StackPanel)の一番上の要素にGotFocus / LostFocusイベントが表示されず、アイデアが見つかりません。

回答:


182

これを行う最も簡単な方法は、「ItemTemplate」プロパティではなく、「ItemContainerStyle」のテンプレートを提供することです。以下のコードでは、2つのデータテンプレートを作成しています。1つは「未選択」状態用、もう1つは「選択済み」状態用です。次に、アイテムを含む実際の「ListBoxItem」である「ItemContainerStyle」のテンプレートを作成します。デフォルトの「ContentTemplate」を「未選択」状態に設定し、「IsSelected」プロパティがtrueの場合にテンプレートを交換するトリガーを提供します。(注:単純化するために、コードビハインドの「ItemsSource」プロパティを文字列のリストに設定しています)

<Window.Resources>

<DataTemplate x:Key="ItemTemplate">
    <TextBlock Text="{Binding}" Foreground="Red" />
</DataTemplate>

<DataTemplate x:Key="SelectedTemplate">
    <TextBlock Text="{Binding}" Foreground="White" />
</DataTemplate>

<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
    <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
        </Trigger>
    </Style.Triggers>
</Style>

</Window.Resources>
<ListBox x:Name="lstItems" ItemContainerStyle="{StaticResource ContainerStyle}" />

ありがとうございます。<ListBox ItemContainerStyle =” {StaticResource ContainerStyle}” ItemsSource =” {Binding MyData}” />を投稿に含めてください。そうすれば、ブログを検索する必要がなくなります。
Shimmy Weitzhandler 2009

2
ListBoxのContainerStyleの設定で遭遇した1つの問題は、テーマとの非互換性を引き起こすことです。私はあなたのアプローチを使用しましたが、WPF Futuresセットのテーマを適用すると、ListBoxItemsはテーマのスタイルではなくデフォルトのスタイルを持ちました。私の場合、黒の背景に黒のテキストと一般的な醜さ。私はまだ別のアプローチを探しています。おそらくDataTemplateトリガーを使用しています。
ベニージョビガン、

1
また、新しいItemContainerStyleをテーマと互換性を持たせたい場合は、テーマからのものをベースにする必要があります。これを行うにはBasedOn="{StaticResource {x:Type ListBoxItem}}"、ListBox で使用します。これは、TreeViewなどの他のコントロールにも適用されます。
Benny Jobigan、

5
これを使用すると、難解なXAMLエラーが発生しないように、ResourcesセクションのStyleの上にDataTemplatesを宣言する必要があることがわかりました。そのことについて、ただの前向きな話です。
Rob Perkins

8

アイテムが選択されたときにスタイルを設定するか、必要なことは、ListBoxItem親を取得し、<DataTemplate>スタイルが変更されたときにスタイルの変更をトリガーIsSelectedするだけです。たとえば、次のコードTextBlockはデフォルトのForeground色が緑色のを作成します。アイテムが選択されると、フォントがに変わり、マウスをアイテムの上に置くと黄色に変わります。そうすれば、わずかに変更したいすべての状態に対して他の回答で提案されているように、個別のデータテンプレートを指定する必要がありません。

<DataTemplate x:Key="SimpleDataTemplate">
    <TextBlock Text="{Binding}">
        <TextBlock.Style>
            <Style>
                <Setter Property="TextBlock.Foreground" Value="Green"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={
                        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
                                 Value="True">
                        <Setter Property="TextBlock.Foreground" Value="Red"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={
                        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
                                 Value="True">
                        <Setter Property="TextBlock.Foreground" Value="Yellow"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</DataTemplate>

1
質問で書いたように、選択した場合、実際にはより多くの情報が表示されます(「選択すると、異なる/より多くの情報が表示されます」)。それでも、これがいくつかの要素の可視性の切り替え(要素がサイズを占めるかどうかを含む)で機能するようにできる場合、これは実行可能な解決策になります。しばらくの間WPFを使用していません。
Daniel Beck 14

6

また、スタックパネルはフォーカス可能ではないため、フォーカスを取得することは決してないことに注意してください(/ really /にフォーカスしたい場合は、Focusable = Trueを設定してください)。ただし、このようなシナリオで覚えておくべき重要な点は、StackpanelがTreeViewItem(この場合はItemContainer )のであることです。Micahが示唆するように、itemcontainerstyleを調整することは良いアプローチです。

おそらく、DataTemplatesを使用して、RelativeSouceマークアップ拡張を使用してlistviewitemを探すdatatriggersなどを実行できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.