1
votes

I generate ListBox menu from XML. I use datatemplate to style the behavior of listboxitems on selection and other states. I need to hide all textblocks in all listboxitems on selection of the item which gets a value ‘retract’ from XML. Now, I am able to hide texblock only in listboxitem which has this value but cannot hide textblocks in other listboxitems. I am wondering if someone can help. Thank you in advance.

<DataTemplate x:Key="ListBoxItemDataTemplate">
        <Grid x:Name="DataItem">
            <Image x:Name="IconImage" Source="{Binding XPath=@icon}" Height="16" Margin="16,0,0,0" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Left" />
            <TextBlock x:Name="ListboxIemtextBlock" Text="{Binding XPath=@name}" />
            <Image x:Name="ArrowImage" Height="10" Source="Resources/Images/arrow_collapsed_grey.png" Visibility="{Binding XPath=@state}"/>
        </Grid>
         <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True">
                <Setter TargetName="ListboxIemtextBlock" Property="Foreground" Value="White"/>
                <Setter TargetName="IconImage" Property="Source" Value="{Binding XPath=@iconSelected}"/>
                <Setter TargetName="IconImage" Property="Height" Value="16"/>
                <Setter TargetName="ArrowImage" Property="Source" Value="Resources/Images/arrow_collapsed_white.png"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True">
                <Setter TargetName="ListboxIemtextBlock" Property="Foreground" Value="#FF6dacbe"/>
            </DataTrigger>
            <MultiDataTrigger>         
                <MultiDataTrigger.Conditions>           
                    <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True" />           
                    <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True" />         
                </MultiDataTrigger.Conditions>         
                <Setter TargetName="ListboxIemtextBlock" Property="Foreground" Value="White"/>      
            </MultiDataTrigger> 
            <DataTrigger Binding="{Binding XPath=@retract}" Value="True" >             
                <Setter TargetName="ListboxIemtextBlock" Property="Visibility" Value="Hidden"/>      
            </DataTrigger> 
         </DataTemplate.Triggers>
    </DataTemplate>

It looks like I cannot control the visibility of all texblocks from a datatemplate. I think it should be done in the ListBox style. I was thinking to switch datatemplates with a second datatemplate that does not have texblock at all. I wanted to use multitrigger for conditions with values isSelected and XML-Binding to Binding="{XPath=@retract}. However, I cannot assign XPath binding for multitrigger in Listbox style. Perphaps, you might help to bind it correctly or have a better idea on how to hide texblocks.

<Style x:Key="ListBoxItemContainerStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="ContentTemplate" Value="{StaticResource ListBoxItemDataTemplate}"/>
        <Setter Property="Template" >
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <ContentPresenter x:Name="contentPresenter"/>
                    <ControlTemplate.Triggers>      
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Binding="{XPath=@retract}" Value="true"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="ContentTemplate" Value="{StaticResource SelectedListBoxItemDataTemplate}"/> 
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>  
    </Style> 

I populated XML with XMLDataProvider. I reference to xml this way:

<XmlDataProvider x:Key="PagesData" XPath="/Pages" Source="Data/DataSource.xml" />

XML:

<Pages xmlns="">
<page name="Item 1" icon="Resources/Iocn1.png" retract="False" />
<page name="Item 2" icon="Resources/Iocn2.png" retract="False" />
<page name="Item 3" icon="Resources/Iocn3.png" retract="True" /></Pages>
1

1 Answers

2
votes

You can bind to the SelectedItem.retract for the Parent ListBox. This is a working example using Path instead of XPath (since I don't have your XML source) but you should be able to get it to work the same way

Add this trigger in the DataTemplate

<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=SelectedItem.retract}" Value="True" >
    <Setter TargetName="ListboxIemtextBlock" Property="Visibility" Value="Hidden"/>
</DataTrigger>