Using bindings in DataTrigger condition

stiank81 picture stiank81 · Feb 10, 2010 · Viewed 19.6k times · Source

Let's say I have the following simple classes:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PersonHolder
{
    public Person CurrentPerson { get; set; }
    public int ActiveId { get; set; }
}

Now I have a grid with an instance of class PersonHolder as DataContext, and in the grid I have a StackPanel which is bound to the CurrentPerson of PersonHolder - showing its data:

<Grid>
    <StackPanel x:Name="PersonPanel" DataContext="{Binding CurrentPerson}">
        <TextBlock Text="{Binding Id}" />
        <TextBlock Text="{Binding Name}" />            
    </StackPanel>        
</Grid>

So - to the question: How can I give the StackPanel a green background when the CurrentPerson has an Id matching the ActiveId of the PersonHolder (yeah, very useful, but this is just an extremely simplified example..). My thought is that this is something one uses a trigger for, but can I use bindings in my trigger condition value? If so I could do something like this:

<Grid x:Name="Foo">
    <StackPanel x:Name="PersonPanel" DataContext="{Binding CurrentPerson}">
        <TextBlock Text="{Binding Id}" />
        <TextBlock Text="{Binding Name}" />
        <StackPanel.Triggers>
            <DataTrigger Binding="{Binding Id}" Value="{Binding ElementName=Foo, Path=ActiveId}">
                <Setter TargetName="PersonPanel" Property="Background" Value="Green" />
            </DataTrigger>
        </StackPanel.Triggers>
    </StackPanel>        
</Grid>

But this doesn't work. How can I solve this?

Answer

code-zoop picture code-zoop · Feb 11, 2010

You can't use a binding on the Value property, but you can get around this by using a MultiBinding and an IMultiValueConverter. I would define my Trigger in a Style in e.g. the Window.Resources, which would give something like this:

<Window.Resources>
    <local:SomeMultiConverter x:Key="someMultiConverter" />
    <Style x:Key="someStyle" TargetType="StackPanel">
        <Setter Property="StackPanel.Background" Value="Red" />
        <Style.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource someMultiConverter}">
                        <Binding Path="Id"></Binding>
                        <Binding ElementName="Foo" Path="DataContext.ActiveId"></Binding>
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="StackPanel.Background" Value="Green" />
            </DataTrigger>
        </Style.Triggers>
    </Style> 
</Window.Resources>
<Grid x:Name="Foo">
    <StackPanel DataContext="{Binding CurrentPerson}" Style="{StaticResource someStyle}" >
        <TextBlock Text="{Binding Id}" />
        <TextBlock Text="{Binding Name}" />
    </StackPanel>
</Grid>

See this link for an example on MultiBinding and IMultiValueConverter. They're fairly easy to write.