Dave Lowther
Dave Lowther

Reputation: 408

How to set visibility of a member of a datatemplate when the template is applied?

I have a ListBox that specifies ItemContainerStyle. The ItemContainerStyle uses Triggers to set the ContentTemplate.

I would like to set the Visibility of a ContentControl (named "ExpanderContent") in the ContentTemplate when the template is applied. I'd prefer to use the value of an attached property set on the ListBoxItem, if possible.

Perhaps it will help make the question clearer to see this one example of what I've tried using a Style applied to the ContentControl (named "ExpanderContent"). I realize that the Style is not set on the ContentControl in the code below. I have set it and seen it applied and seen that there is no error regarding resolving the attached property.

<ListBox ItemContainerStyle="{StaticResource lbcStyle}"/>

<Style TargetType="ListBoxItem" x:Key="lbcStyle">
  <Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
      <Setter Property="ContentTemplate" Value="{StaticResource editable}"/>
    </Trigger>
  </Style.Triggers>
  <Setter Property="ContentTemplate" Value="{StaticResource nonEditable}"/>
</Style>

<DataTemplate x:Key="nonEditable">
  <Grid Width="Auto" Height="Auto">
    ...
    <ContentControl Name="ExpanderContent" Visibility="Collapsed" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="12"></ContentControl>
  </Grid>
</DataTemplate>
<DataTemplate x:Key="editable">
  <Grid x:Name="grdEditable" Width="Auto" Height="Auto">
    ...
    <ContentControl Name="ExpanderContent" Visibility="Collapsed" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="12"></ContentControl>
  </Grid>
</DataTemplate>

<Style x:Key="editorContentControl" TargetType="{x:Type ContentControl}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding (local:AttachedProperties.IsExpanded),RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}" Value="True">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding (local:AttachedProperties.IsExpanded),RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}" Value="False">
            <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </Style.Triggers>
    <Setter Property="Visibility" Value="Visible"/>
</Style>

The real world application of this nonsense is that I have a list box and the items in the list box have templates that change when selected. The templates have an expander and I'd like to leave the expander expanded even when the item is not selected. As it is now, whenever I change the list box selection, the content template is reapplied in its original state, which is collapsed - so I can never have more than one expanded at a time.

alt text

Upvotes: 0

Views: 1771

Answers (1)

John Bowen
John Bowen

Reputation: 24453

The simplest solution, rather than trying to pass visual state values around between different templates, is just to use a single DataTemplate for your ContentTemplate and just use triggers in that template to show and hide the appropriate controls for the current selection state. That way you're not replacing the expander control every time you switch states.

Upvotes: 1

Related Questions