Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTemplate multiple data triggers to same element and property

How can I have multiple data triggers work on the same element and property?

        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding ElementName=RootGrid,Path=IsMouseOver}" Value="True">
                <Setter TargetName="SelectionGrid" Property="Opacity" Value="0.5" />
            </DataTrigger>
            <DataTrigger Binding="{Binding ElementName=RootGrid,Path=IsMouseOver}" Value="False">
                <Setter TargetName="SelectionGrid" Property="Opacity" Value="0.0" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Selected}" Value="True">
                <Setter TargetName="SelectionGrid" Property="Opacity" Value="1.0" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Selected}" Value="False">
                <Setter TargetName="SelectionGrid" Property="Opacity" Value="0" />
            </DataTrigger>
        </DataTemplate.Triggers>

Notice how I'm targeting SelectionGrid's Opacity property. How can I achieve this effect? This is supposed to replicate the hover selection box that Windows 7 has. So when it both is Selected and IsMouseOver, I would like it to show me the Selected state.

like image 262
Daniel A. White Avatar asked Sep 16 '11 11:09

Daniel A. White


1 Answers

You could use MultiDataTrigger or a DataTrigger with a MultiBinding and a BooleanOrConverter.

But I think the easiest solution to your problem is to use a MultiBinding for Opacity where you bind to both Selected and IsMouseOver

<DataTemplate>
    <Grid x:Name="SelectionGrid">
        <Grid.Opacity>
            <MultiBinding Converter="{StaticResource OpacityConverter}"> 
                <Binding RelativeSource="{RelativeSource Self}" Path="IsMouseOver"/>
                <Binding Path="Selected"/>
            </MultiBinding>
        </Grid.Opacity>
    </Grid>
    <!-- ... -->
</DataTemplate>

And in the OpacityConverter you decide the Opacity value

public class OpacityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool isMouseOver = (bool)values[0];
        bool selected = (bool)values[1];
        if (selected == true)
        {
            return 1.0;
        }
        else if (isMouseOver == true)
        {
            return 0.5;
        }
        return 0.0;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Edit: Here is how you can do it with a DataTrigger and MultiDataTrigger

<DataTemplate>
    <Grid x:Name="SelectionGrid"
            Opacity="0"
            Background="Blue">
    </Grid>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Selected}" Value="True">
            <Setter TargetName="SelectionGrid" Property="Opacity" Value="1.0"/>
        </DataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding ElementName=SelectionGrid, Path=IsMouseOver}" Value="True"/>
                <Condition Binding="{Binding Path=Selected}" Value="False"/>
            </MultiDataTrigger.Conditions>
            <Setter TargetName="SelectionGrid" Property="Opacity" Value="0.5"/>
        </MultiDataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>
like image 90
Fredrik Hedblad Avatar answered Oct 26 '22 22:10

Fredrik Hedblad