WPF Trigger for IsSelected in a DataTemplate for ListBox items

WpfTriggersListboxItemtemplateEvent Triggers

Wpf Problem Overview


I have a listbox, and I have the following ItemTemplate for it:

<DataTemplate x:Key="ScenarioItemTemplate">
	<Border Margin="5,0,5,0"
			Background="#FF3C3B3B"
			BorderBrush="#FF797878"
			BorderThickness="2"
			CornerRadius="5">
		<DockPanel>
			<DockPanel DockPanel.Dock="Top"
					   Margin="0,2,0,0">
				<Button HorizontalAlignment="Left"
						DockPanel.Dock="Left"
						FontWeight="Heavy"
						Foreground="White" />
				<Label Content="{Binding Path=Name}"
					   DockPanel.Dock="Left"
					   FontWeight="Heavy"
					   Foreground="white" />
				<Label HorizontalAlignment="Right"
					   Background="#FF3C3B3B"
					   Content="X"
					   DockPanel.Dock="Left"
					   FontWeight="Heavy"
					   Foreground="White" />
			</DockPanel>
			<ContentControl Name="designerContent"
							Visibility="Collapsed"
							MinHeight="100"
							Margin="2,0,2,2"
							Content="{Binding Path=DesignerInstance}"
							Background="#FF999898">
			</ContentControl>
		</DockPanel>
	</Border>
</DataTemplate>

As you can see the ContentControl has Visibility set to collapsed.

I need to define a trigger that causes the Visibility to be set to "Visible"

when the ListItem is selected, but I can't figure it out.

Any ideas?

UPDATE: Of course I could simply duplicate the DataTemplate and add triggers to the ListBox in question to use either one or the other, but I want to prevent duplicating this code.

Wpf Solutions


Solution 1 - Wpf

You can style your ContentControl such that a trigger fires when its container (the ListBoxItem) becomes selected:

<ContentControl 
    x:Name="designerContent"
    MinHeight="100"
    Margin="2,0,2,2"
    Content="{Binding Path=DesignerInstance}"
    Background="#FF999898">
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="Visibility" Value="Collapsed"/>
            <Style.Triggers>
                <DataTrigger
                        Binding="{Binding
                            RelativeSource={RelativeSource
                                Mode=FindAncestor,
                                AncestorType={x:Type ListBoxItem}},
                                Path=IsSelected}"
                        Value="True">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

Alternatively, I think you can add the trigger to the template itself and reference the control by name. I don't know this technique well enough to type it from memory and assume it'll work, but it's something like this:

<DataTemplate x:Key="ScenarioItemTemplate">
    <DataTemplate.Triggers>
        <DataTrigger
                Binding="{Binding
                    RelativeSource={RelativeSource
                        Mode=FindAncestor,
                        AncestorType={x:Type ListBoxItem}},
                        Path=IsSelected}"
                Value="True">
            <Setter
                TargetName="designerContent"
                Property="Visibility"
                Value="Visible"/>
        </DataTrigger>
    </DataTemplate.Triggers>

    ...
</DataTemplate>

Solution 2 - Wpf

@Matt, Thank you!!!

Just had to add a trigger for IsSelected == false as well, and now it works like a charm!

<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
    <Setter Property="Visibility" Value="Collapsed"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="False">
            <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTimothyPView Question on Stackoverflow
Solution 1 - WpfMatt HamiltonView Answer on Stackoverflow
Solution 2 - WpfTimothyPView Answer on Stackoverflow