Set IsEnabled Property of ComboBox Based on SelectedItem
Asked Answered
D

3

6

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>
Dire answered 9/2, 2011 at 21:17 Comment(1)
FWIW, I got this working with a style and I prefer that to the converter because it is all in XAML. I did not need a setter to specify that the IsEnabled should be true when the trigger is not active. I'm posting this for others who come across this question, so that they don't get the impression that it cannot be done with a style.Refugee
E
10

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();
    }
}
Edra answered 9/2, 2011 at 21:24 Comment(3)
I can't seem to get the binding to NullToFalseConverter to work properly. I keep getting an exception: "Cannot find resource named 'NullToFalseConverter'. Resource names are case sensitive.". Help? Sorry, I'm pretty new to WPF :-/Dire
@Dire You need to actually declare an instance of the Converter, somewhere. Note that @Edra is referencing it as a StaticResource. That means you need an entry in the Resources collection of whatever contains your ComboBox that looks something like this: <NullToFalseConverterClass x:Key=NullToFalseConverter/>Invercargill
I think the implementation of the Converter is wrong, it should be <return value != null> and it is not required do declare an instance. At least I don not have one and it works.Bookish
M
6

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}"/>
Murderous answered 9/2, 2011 at 21:24 Comment(1)
Upvote as this works as well. I decided the converter option was cleaner though so I marked it as correct.Dire
W
0

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

Wisner answered 9/2, 2011 at 21:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.