1

I am creating a dynamic form in WPF (C#) in which a combobox's contents are used to determine what the next combobox will be. For instance, the first combobox has these values:

Beers
Juices

The second combobox will then be either

Carlsberg
Heineken

or

Apple
Orange

depending on the value of the first combobox. However, I need the second combobox to start in the open position, as if the user had already clicked on it. I had considered using a listbox to display the choices, but it really should be a combobox and it really does need to start in the open position. Is there any way to have the combobox start in the open position, as if the user had already clicked it, in order to display all the possible options?

Thanks!

H.B.
  • 166,899
  • 29
  • 327
  • 400
dotancohen
  • 30,064
  • 36
  • 138
  • 197
  • take a look at http://stackoverflow.com/questions/4327012/wpf-cascading-comboboxes-dependent-ones-dont-update – Glory Raj Dec 11 '11 at 19:42
  • @pratapchandra: Although certainly full of useful info, that question is unrelated to this question. To clarify, a combobox does not display all it's options in its initial state, only after the user clicks on it. In the unique constraints of my current project, however, I would like that when the combobox is dynamically added (like in the question that you linked to) that all the options be displayed (the 'open' state) as if the user had clicked on it. – dotancohen Dec 11 '11 at 19:57

1 Answers1

2

A ComboBox can be programmatically opened by setting the property IsDropDownOpen. To demonstrate this:

XAML:

<StackPanel>
    <ComboBox x:Name="comboBoxOne"
              SelectionChanged="OnComboBoxOneSelectionChanged" >
        <ComboBoxItem Content="Combo Box 1 - Item 1" />
        <ComboBoxItem Content="Combo Box 1 - Item 2" />
    </ComboBox>
    <ComboBox x:Name="comboBoxTwo">
        <ComboBoxItem Content="Combo Box 2 - Item 1" />
        <ComboBoxItem Content="Combo Box 2 - Item 2" />
    </ComboBox>
</StackPanel>

in code behind:

private void OnComboBoxOneSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    comboBoxTwo.IsDropDownOpen = true;
}

Hope this helps!

Edit

If you don't want to use code-behind you have many options. For example you could create an attached behaviour or use a converter.

For example with a converter:

XAML:

<StackPanel>
    <ComboBox x:Name="comboBoxOne"
              SelectionChanged="OnComboBoxOneSelectionChanged" >
        <ComboBoxItem Content="Combo Box 1 - Item 1" />
        <ComboBoxItem Content="Combo Box 1 - Item 2" />
    </ComboBox>
    <ComboBox x:Name="comboBoxTwo"
              IsDropDownOpen="{Binding ElementName=comboBoxOne, Path=SelectedItem, Mode=OneWay, Converter={l:NullToBoolConverter}}">
        <ComboBoxItem Content="Combo Box 2 - Item 1" />
        <ComboBoxItem Content="Combo Box 2 - Item 2" />
    </ComboBox>
</StackPanel>

Converter:

public class NullToBoolConverter : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value != null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Here - each time the selection changes in the first ComboBox the Binding on the second is updated, and the Converter executed. I'm checking against null since we don't want it to be open on startup (in this example).

All of this assumes you already know how to set your ItemsSource dynamically using triggers, and that the real question is how to get the second ComboBox in an already open state :)

FunnyItWorkedLastTime
  • 3,225
  • 1
  • 22
  • 20