WPF MultiDataTrigger AND condition

Steven picture Steven · Aug 13, 2015 · Viewed 21.6k times · Source

I would like to enable a button only when both of my two datagrids have selected items. Right now it is enabled when either of the datagrids have selections. Any ideas?

<Button x:Name="button" Content="Z" Grid.Column="1" Margin="0,240,0,0" VerticalAlignment="Top" FontFamily="Wingdings 3" FontSize="21.333" ToolTip="Set the selected alarm for the selected alarm time">
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="IsEnabled" Value="True" />
            <Setter Property="Opacity" Value="1" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=alarmProfilesDataGrid, Path=SelectedItem}" Value="{x:Null}"/>
                        <Condition Binding="{Binding ElementName=alarmFilesDataGrid, Path=SelectedItem}" Value="{x:Null}"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Property="IsEnabled" Value="False" />
                        <Setter Property="Opacity" Value=".5" />
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Answer

Yogesh picture Yogesh · Aug 13, 2015

Here is what happens with your code: Instead of both conditions to be true when either of the datagrids have selections, the conditions are only met when both of the datagrid don't have selections.

When the program starts, both the datagrids are nulls, so your condition is met. Now if you make selection in either of your grids, your condition is never met and the value of IsEnabled remains True i.e. the original value.

To correct this problem, you need a converter:

public class NotNullToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool result = value == null ? false : true;

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

and

<Style TargetType="Button">
    <Setter Property="IsEnabled" Value="False" />
    <Setter Property="Opacity" Value=".5" />
    <Style.Triggers>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding ElementName=alarmProfilesDataGrid, Path=SelectedItem, Converter={StaticResource NotNullToBoolConverter}}" Value="True"/>
        <Condition Binding="{Binding ElementName=alarmFilesDataGrid, Path=SelectedItem, Converter={StaticResource NotNullToBoolConverter}}" Value="True"/>
        </MultiDataTrigger.Conditions>
        <MultiDataTrigger.Setters>
        <Setter Property="IsEnabled" Value="True" />
        <Setter Property="Opacity" Value="1" />
        </MultiDataTrigger.Setters>
    </MultiDataTrigger>
    </Style.Triggers>
</Style>