Set IsEnabled Property of ComboBox Based on SelectedItem

14k views Asked by At

I want to enable/disable a ComboBox based on if there is an item selected in another ComboBox. I was able to get it working by setting a trigger on the Style, but that overrides my custom global style for the combobox. Is there another way to get the same functionality without losing my style?

<ComboBox Grid.Column="1" Grid.Row="1"
              Name="AnalysisComboBox" 
              MinWidth="200"
              VerticalAlignment="Center" HorizontalAlignment="Left"
              ItemsSource="{Binding Path=AvailableAnalysis}">

        <ComboBox.Style>
            <Style TargetType="{x:Type ComboBox}">
                <Setter Property="IsEnabled" Value="True" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding SelectedItem,ElementName=ApplicationComboBox}" Value="{x:Null}">
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ComboBox.Style>
    </ComboBox>
3

There are 3 answers

3
ColinE On BEST ANSWER

You don't need to do this via a Style, you can bind the IsEnabled property directly using a value converter as follows:

<ComboBox Grid.Column="1" Grid.Row="1"
              Name="AnalysisComboBox" 
              MinWidth="200"
              VerticalAlignment="Center" HorizontalAlignment="Left"
              IsEnabled={Binding SelectedItem, ElementName=ApplicationComboBox, Converter={StaticResource NullToFalseConverter}}"
              ItemsSource="{Binding Path=AvailableAnalysis}"/>

Where NullToFalseConverter is a key to an instance of the followsing converter:

public class NullToFalseConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value == null;
    }

    public object ConvertBack(object value, Type targetType,
      object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
1
Pavlo Glazkov On

Yes, you can set BasedOn attribute to "inherit" your global style:

<ComboBox Grid.Column="1" Grid.Row="1"
          Name="AnalysisComboBox" 
          MinWidth="200"
          VerticalAlignment="Center" HorizontalAlignment="Left"
          ItemsSource="{Binding Path=AvailableAnalysis}">
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}"
               BasedOn="{StaticResource {x:Type ComboBox}}">
            <Setter Property="IsEnabled" Value="True" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding SelectedItem,ElementName=ApplicationComboBox}" Value="{x:Null}">
                    <Setter Property="IsEnabled" Value="False" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ComboBox.Style>
</ComboBox>

Instead of {StaticResource {x:Type ComboBox}} you can set the key of you global style (if it is not implicit).

But for this particular task you don't need to define a style. You can just set a binding to IsEnabled property and use a converter to convert selected item of another combo box to a boolean:

<ComboBox Grid.Column="1" Grid.Row="1"
              Name="AnalysisComboBox" 
              MinWidth="200"
              VerticalAlignment="Center" HorizontalAlignment="Left"
              ItemsSource="{Binding Path=AvailableAnalysis}"
          IsEnabled="{Binding SelectedItem,ElementName=ApplicationComboBox, Converter={StaticResource NotNullConverter}"/>
0
Daniel Rose On

You could simply have a "normal" binding, with a value converter for changing "value exists" => true, "value is null" => false.