Is it possible to define triggers at the grid level that update grid's child properties?
I tried something like that but without success:
ViewModel:
public class MyViewModel
{
public bool PropertyA {get;set;}
public bool PropertyB {get;set;}
}
(I omitted all the PropertyChanged stuff for brievety)
XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="ControlA" Grid.Row="0" />
<TextBlock x:Name="ControlB" Grid.Row="1" />
<Grid.Triggers>
<!-- Condition A -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PropertyA}" Value="false"/>
<Condition Binding="{Binding PropertyB}" Value="true"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="ControlA" Property="Text" Value="Blah"/>
<Setter TargetName="ControlB" Property="Text" Value="Blah"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<!-- Conditon B -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PropertyA}" Value="false"/>
<Condition Binding="{Binding PropertyB}" Value="false"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="ControlA" Property="Text" Value="Blah"/>
<Setter TargetName="ControlB" Property="Text" Value="Blah"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<!-- Condition C -->
<DataTrigger Binding="{Binding PropertyA}" Value="true">
<Setter TargetName="ControlA" Property="Text" Value="Blah"/>
<Setter TargetName="ControlB" Property="Text" Value="Blah"/>
</DataTrigger>
</Grid.Triggers>
</Grid>
But the compiler complains about
The name "ControlA" is not recognized.
The name "ControlB" is not recognized.
The member "Text" is not recognized or is not accessible.
The member "Text" is not recognized or is not accessible.
Is it possible to define triggers at the grid level that update grid's child properties?
No. Setting the TargetName of a Setter only makes sense in a ControlTemplate where there is an element with a matching name.
Generally speaking, a Setter can only set a property of the element to which the style or trigger is applied to.
What you should do instead is to create a style with triggers for the TextBlock(s), e.g.:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PropertyA}" Value="false"/>
<Condition Binding="{Binding PropertyB}" Value="true"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Text" Value="Blah"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<TextBlock x:Name="ControlA" Grid.Row="0" />
<TextBlock x:Name="ControlB" Grid.Row="1" />
</Grid>
Related
I have three buttons that differ only in the text displayed, the parameter they pass to the command and a value compared in a trigger for the image. Is there a way to coalesce this into a single template to eliminate all the duplicate XAML?
Style Definition:
<Style TargetType="{x:Type Button}" x:Key="myGridHeaderButton">
<Setter Property="Background" Value="Blue" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderThickness="0,0,1,0" BorderBrush="white">
<ContentPresenter Margin="1" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightBlue" />
</Trigger>
</Style.Triggers>
</Style>
Button Declaration:
<Button Grid.Column="2" Style="{StaticResource myGridHeaderButton}" Command="{Binding Path=ColumnHeaderClickCommand}" CommandParameter="Description">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Custodian" Margin="3,0,0,0" />
<Image Grid.Column="2" Width="16" Height="16">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/Resources/Sort.Unsorted.png" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=SortAscending}" Value="True" />
<Condition Binding="{Binding Path=SortColumn}" Value="Description" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Source" Value="/Resources/Sort.Ascending.png" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=SortAscending}" Value="False" />
<Condition Binding="{Binding Path=SortColumn}" Value="Description" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Source" Value="/Resources/Sort.Descending.png" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Grid>
</Button>
I figure the Command and CommandParameter would be declared just as they are now. If it was simply a difference in text, I think just placing the <ContentPresenter /> in the right place would work, but there is a style embedded in the image that has a couple of triggers based on different values and I can't figure out how to move all that stuff to the template and still be able to define the differing trigger values.
In this case, the trigger values in question always match the CommandParameter value... Would I somehow bind to that?
Thanks.
J
I am trying to setup a grid's visibility using a multidatatrigger. The condition for making it visible is PropertyA==null && PropertyB==false. I am not sure how PropertyA condition is to be written. My attempt is here (but not working):
<Grid>
<Grid.Style>
<Style>
<Setter Property="Control.Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding PropertyA}" Value="{x:Null}"/>
<Condition Binding="{Binding PropertyB}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Control.Visibility" Value="Visible" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
Could someone advise pls.
This is the style that I have used, it is for Button but it works as expected
<Style TargetType="Button" x:Key="btnTakePhoto">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Comment}" Value="{x:Null}"/>
<Condition Binding="{Binding ResponseNumber}" Value="{x:Null}"/>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
Try to take the Style out of your Grid and include it in your UserControl.Resources tag.
You would use it like so:
<Button Style="{StaticResource btnTakePhoto}"/>
There is absolutely no reason for your xaml not to work.
EDIT
Also I have this code in my other UserControl:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Style>
<Style>
<Setter Property="Grid.Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=btnShowHide, Path=IsChecked}" Value="True">
<Setter Property="Grid.Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
<ToggleButton MinHeight="150" Width="50" Content=">" Name="btnShowHide">
I have a ListBox which Item's ContentPresenter is changed by MultiDataTrigger depending on some IsTool and IsAlerting boolean properties:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="LayerTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource PageHeaderContentControlStyle}">
<layers:PageHeader/>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="ToolTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource ToolHeaderContentControlStyle}">
<layers:ToolHeader/>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="LayerAlertTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource PageHeaderAlertContentControlStyle}">
<layers:PageHeader/>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="ToolAlertTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource ToolHeaderAlertContentControlStyle}">
<layers:ToolHeader/>
</ContentControl>
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="EmptyListViewSelection">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderBrush="Transparent"
BorderThickness="0"
Background="{TemplateBinding Background}"
Margin="2"
FocusVisualStyle="{x:Null}">
<ContentPresenter DataContext="{Binding}" Name="contentPresenter"/>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsTool}" Value="False">
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource LayerTemplate}"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsTool}" Value="True">
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource ToolTemplate}"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsTool}" Value="False"/>
<Condition Binding="{Binding IsAlerting}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource LayerAlertTemplate}"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsTool}" Value="True"/>
<Condition Binding="{Binding IsAlerting}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource ToolAlertTemplate}"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox Name="listView"
BorderThickness="0"
ItemsSource="{Binding Pages}"
SelectedValue="{Binding SelectedPage}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ItemContainerStyle="{StaticResource EmptyListViewSelection}"
IsTabStop="False"
FocusVisualStyle="{x:Null}"
Focusable="False" Background="{x:Null}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" MaxWidth="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=ActualWidth}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<GroupBox Name="pageBox" IsEnabled="{Binding Visible}" Grid.Row="1" DataContext="{Binding Path=SelectedValue, ElementName=listView}">
<GroupBox.Header>
<Label Content="{Binding Name}" Padding="0"/>
</GroupBox.Header>
<ContentControl Content="{Binding}"/>
</GroupBox>
</Grid>
If the notification of IsAlerting property change (via INotifyPropertyChange) is fired approximately one time per second, the memory usage of my application increases from 230MB up to 804MB for 15 minutes and the application finally crashes with the following call stack:
Exception Info: System.Reflection.TargetInvocationException
Stack:
at System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlReader, System.Xaml.XamlObjectWriter)
at System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlObjectWriter)
at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(System.Windows.DependencyObject, System.Windows.Markup.IComponentConnector, System.Windows.Markup.IStyleConnector, System.Collections.Generic.List`1<System.Windows.DependencyObject>, System.Windows.UncommonField`1<System.Collections.Hashtable>)
at System.Windows.FrameworkTemplate.LoadContent(System.Windows.DependencyObject, System.Collections.Generic.List`1<System.Windows.DependencyObject>)
at System.Windows.StyleHelper.ApplyTemplateContent(System.Windows.UncommonField`1<System.Collections.Specialized.HybridDictionary[]>, System.Windows.DependencyObject, System.Windows.FrameworkElementFactory, Int32, System.Collections.Specialized.HybridDictionary, System.Windows.FrameworkTemplate)
at System.Windows.FrameworkTemplate.ApplyTemplateContent(System.Windows.UncommonField`1<System.Collections.Specialized.HybridDictionary[]>, System.Windows.FrameworkElement)
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
at System.Windows.UIElement.Measure(System.Windows.Size)
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.ContextLayoutManager.UpdateLayoutCallback(System.Object)
at System.Windows.Media.MediaContext+InvokeOnRenderCallback.DoWork()
at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
at System.Windows.Media.MediaContext.RenderMessageHandlerCore(System.Object)
at System.Windows.Media.MediaContext.RenderMessageHandler(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
.............
any ideas?
Not sure about the memory leak, but i wouldn't change the contenttemplate like this. If you set the ContentTemplate on a ContentPresenter, the ContentSource property of the ContentPresenter (which is 'Content' by default) will be overruled/ignored, the Content property will be empty, and your ContentTemplate doesn't have a datacontext anymore.
It's better to set the ContentTemplate in a style setter and use style triggers to change it. The default ContentSource of the ContentPresenter will do the rest.
I suspect this might solve your memory leak.
Your memory leak may be caused by the situation described in Can bindings create memory leaks in WPF?, perhaps exacerbated by virtualization in the list box (or maybe lack thereof if you have a lot of items and it is allocating them all at once). The fact that you have a System.Reflection.TargetInvocationException makes me think you are binding to something that isn't an INotifyPropertyChanged, which then has to use reflection to figure out if values are changing.
In newer versions of Visual Studio (2013, maybe 2012), there is a memory profiler that can show what objects are leaking which may help you narrow your search.
for some reason moving MultiDataTrigger to a separate style solved the problem (there is no memory leak anymore):
<Style TargetType="{x:Type ContentControl}" x:Key="PageToolHeaderContentControlThemeStyle">
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}"/>
<Setter Property="Padding" Value="5,3"/>
....
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Alert}" Value="Warning"/>
<Condition Binding="{Binding IsAcknowledged}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="PART_BorderAlarmFrame" Property="Stroke" Value="Orange"/>
<Setter TargetName="PART_BorderAlarmFrame" Property="Visibility" Value="Visible"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Alert}" Value="Warning"/>
<Condition Binding="{Binding IsAcknowledged}" Value="False"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="PART_BorderAlarmFrame" Property="Visibility" Value="Visible"/>
</MultiDataTrigger.Setters>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundBrush"
Storyboard.TargetProperty="Color"
From="Transparent" To="Orange" Duration="0:0:0.5"
AutoReverse="True"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Alert}" Value="Alarm"/>
<Condition Binding="{Binding IsAcknowledged}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="PART_BorderAlarmFrame" Property="Stroke" Value="Red"/>
<Setter TargetName="PART_BorderAlarmFrame" Property="Visibility" Value="Visible"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Alert}" Value="Alarm"/>
<Condition Binding="{Binding IsAcknowledged}" Value="False"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="PART_BorderAlarmFrame" Property="Visibility" Value="Visible"/>
</MultiDataTrigger.Setters>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundBrush"
Storyboard.TargetProperty="Color"
From="Transparent" To="Red" Duration="0:0:0.5"
AutoReverse="True"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{DynamicResource LightForegroundBrush}"/>
<Setter TargetName="PART_BorderDefaultFrame" Property="Stroke" Value="{StaticResource ButtonPressedBackgroundBrush}"/>
<Setter TargetName="PART_Border" Property="Background" Value="{StaticResource ButtonHoverBackgroundBrush}"/>
</Trigger>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Foreground" Value="{DynamicResource LightForegroundBrush}"/>
<Setter TargetName="PART_BorderDefaultFrame" Property="Stroke" Value="{StaticResource ButtonPressedBackgroundBrush}"/>
<Setter TargetName="PART_Border" Property="Background" Value="{StaticResource ButtonPressedBackgroundBrush}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
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>
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>
Is it possible to use a MultiTrigger to evaluate properties on multiple elements? That don't reside within a template, but are within the Usercontrol/Window.
Example:
<CheckBox x:Name="checkBox1" />
<CheckBox x:Name="checkBox2" />
<CustomControl>
<CustomControl.ContentTemplate>
<DataTemplate>
<DataTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition
SourceName="checkBox1"
Property="IsChecked"
Value="False" />
<Condition
SourceName="checkBox2"
Property="IsChecked"
Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter
Property="Visibility"
Value="Collapsed" />
</MultiTrigger.Setters>
</MultiTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</CustomControl.ContentTemplate>
In a normal Trigger we can use the sourceName to trigger against properties on either of those checkbox controls, but with a MultiTrigger I get build errors when it attempts to find those controls.
Note: The reason I'm using a DataTemplate as opposed to a Style is mentioned here
You can indeed use source name, but your DataTemplate doesn't appear to be defined correctly. I've tried filling out your example which seems to work:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Grid>
<Grid.Resources>
<DataTemplate DataType="{x:Type sys:String}">
<StackPanel>
<TextBlock x:Name="textBlock" Text="{Binding}"></TextBlock>
<CheckBox x:Name="checkBox1" />
<CheckBox x:Name="checkBox2" />
</StackPanel>
<DataTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition
SourceName="checkBox1"
Property="IsChecked"
Value="False" />
<Condition
SourceName="checkBox2"
Property="IsChecked"
Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter
TargetName="textBlock"
Property="Visibility"
Value="Collapsed" />
</MultiTrigger.Setters>
</MultiTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Grid.Resources>
<ContentControl>
<sys:String>Foo</sys:String>
</ContentControl>
</Grid>
</Page>
The problem appears to be that you don't define your CheckBoxes inside your DataTemplate, which is where they need to be.