Search code examples
c#wpfdatatrigger

Compare WPF ItemsControl item to another control's DataContext in Trigger


In my C# / WPF / .NET 4.5 app I would like to implement a Trigger that toggles the Visibility of a control that resides inside the ItemTemplate for an ItemsControl.

I have another control named TheWorkspace. TheWorkspace's DataContext is set to one of the items that populate my ItemsControl. For the item that comprises TheWorkspace's DataContext, I would like to display text that indicates the item we're working on.

I need a Trigger that compares the item's DataContext to TheWorkspace's DataContext and sets the item's Visibility accordingly.

The ItemTemplate:

<DataTemplate>
  <Grid>
    <!-- ... -->
    <TextBlock Grid.Column="2"
               Text="This is the item we're working on."
               Visibility="Hidden">
      <TextBlock.Triggers>
        <!-- Pseudocode -->
        <DataTrigger Binding="{Binding TheWorkspace.DataContext}" Value="{Binding}">
        <!-- /Pseudocode -->
          <Setter Property="Visibility" Value="Visible" />
        </DataTrigger>
      </TextBlock.Triggers>
    </TextBlock>
  </Grid>
</DataTemplate>

This, unfortunately, does not work as intended.

How can I replace the pseudocode to specify a trigger that accomplishes this behavior?


Solution

  • I have solved the problem using a MultiBinding and a MultiValueConverter:

    The ItemTemplate:

    <DataTemplate>
      <!-- ... -->
        <TextBlock Text="This is the item we're working on.">
          <TextBlock.Style>
            <Style TargetType="TextBlock">
              <Setter Property="Visibility"
                      Value="Hidden"/>
              <Style.Triggers>
                <DataTrigger Value="True">
                  <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource samenessConverter}">
                      <Binding ElementName="TheWorkspace"
                               Path="DataContext"/>
                      <Binding/>
                    </MultiBinding>
                  </DataTrigger.Binding>
                  <Setter Property="Visibility"
                          Value="Visible"/>
                </DataTrigger>
              </Style.Triggers>
            </Style>
          </TextBlock.Style>
        </TextBlock>
      <!-- ... -->
    </DataTemplate>
    

    The MultiValueConverter:

    public class SamenessConverter : IMultiValueConverter {
      public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        return values.All(x => x == values[0]);
      }
      // ...
    }