0

I am using WPF C# in my project. My UI contains 4 combo boxes ,each will be loaded by the values from database. Now all 4 comboboxes are displayed at a time. But what I want to do is,First combo box 1 should be visible/displayed then user selects a value say val1,then second combo box should be visible and it should contain values (from database) based on the val1 selected in combobox1 ,and so on. The combo boxes should be interrelated to previous combobox .

How can I achieve this task in WPF?

some of the XAML code: Please Select :

    <Label Grid.Row="1">combobox1 :</Label>
    <ComboBox  Name="PL" Grid.Row="1" Grid.Column="1" Loaded="ComboBox_PLLoaded" SelectionChanged="ComboBox_PLSelectionChanged" />

    <Label Grid.Row="2" HorizontalAlignment="Right">combobox2:</Label>
    <ComboBox Name="Re" Grid.Row="2" Grid.Column="1" VerticalAlignment="Top"  Loaded="ComboBox_RCLoaded" SelectionChanged="ComboBox_RCSelectionChanged"/>

    <Label Grid.Row="3" Margin="89.216,0,60.581,26" Grid.RowSpan="2">combobox3 :</Label>
    <ComboBox Name="CT" Grid.Row="3" Grid.Column="1" Loaded="ComboBox_RCLoaded" SelectionChanged="ComboBox_RCSelectionChanged"/>

    <Label Grid.Row="4" HorizontalAlignment="Right">combobox4 :</Label>
    <ComboBox Name="PT" Grid.Row="4" Grid.Column="1" />

   </Grid>
beginner
  • 463
  • 5
  • 18
  • What is your effort so far ? What problems did you encounter ? – Novitchi S Jun 16 '15 at 10:57
  • i can load data in combobox1 ,user can select a value, but now i execute a query that filters data based on value selected in combobox.I want to load it in combobox2 .and combobox 2 should be displayed only after selecting value in combobox 1 – beginner Jun 16 '15 at 11:03
  • Please show us some code, remove the irrelevant db stuff. – Novitchi S Jun 16 '15 at 11:11
  • edited question with some of the code – beginner Jun 16 '15 at 11:22
  • Some code-behind would be nice, too. So far, your XAML seems good enough for what you're trying to do, you'd just need to control the Combos `Visibility` and `ItemsSource` on the event handlers... Though the best way would be using Bindings, instead of events. – almulo Jun 16 '15 at 12:46

2 Answers2

0

You can make use of the BooleanToVisibilityConverter Class to show and hide the various ComboBoxes in conjunction with a number of bool properties in your code behind or view model. You can set the relevant one to true from the relevant SelectionChanged event handler. Take this simple example:

XAML:

<ComboBox Name="Re" Grid.Row="2" Grid.Column="1" VerticalAlignment="Top"  
    Loaded="ComboBox_RCLoaded" SelectionChanged="ComboBox_RCSelectionChanged" 
    Visibility="{StaticResource BooleanToVisibilityConverter}" />

Code Behind:

private void ComboBox_PLSelectionChanged(object sender, SelectionChangedEventArgs args)
{
    ComboBox comboBox = sender as ComboBox;
    var data = GetDataForNextComboBox(comboBox.SelectedItem);
    NextComboBox.ItemsSource = data;
    // Make next ComboBox visible using BooleanToVisibilityConverter
    BoolPropertyForComboBox2 = true;
}

Obviously, you'll still need to add a reference to the BooleanToVisibilityConverter in your Resources section, declare the new bool properties and implement the GetDataForNextComboBox data access method from the example.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Agreed, though it we're talking about code-behind, I'd set `NextComboBox.Visibility` directly. If talking about MVVM, I'd remove the SelectionChanged event handling and create a Binding to another property too. – almulo Jun 16 '15 at 12:49
  • I tried Visibility="Hidden" attribute in combo box2,and tried to make it visible after loading combobox1. But combo box2 should be loaded once i select a value from combobox1 since based on that value it fetches data from database. But now what I am observing is combobox2's Loaded="ComboBox_RCLoaded" is trying to load it before i select a value in combobox1.Can I make Load attribute of combobox to wait it i select a value from combobox1? – beginner Jun 17 '15 at 03:57
  • @beginner the ComboBox will be loaded, but you can set the visibility based on the selection of comboBox1 at the Selectionchanged event. Have a method to populate the items of ComboBox2, and call that method at the Selectionchanged event of ComboBox1. else please let us know what you want to do exactly at the Loaded event of ComboBox2 – Karuppasamy Jun 17 '15 at 06:25
  • You don't need to do anything in the `Loaded` event handlers. If you use a `BooleanToVisibilityConverter` like my example, then you just set the data bound `bool` property to `false` to hide the `ComboBox`. Then , you just set it to `true` when you want to display it. Simple. – Sheridan Jun 17 '15 at 07:55
0

If you are not using MVVM, then the answer given by Sheridan would hepl you, in that instead of having a bool variable and BoolToVisibility converter, you can just set the Visibility in that event itself(as almulo said).

And if you or anybody using MVVM and having this problem, can have a look at my answer.

I have just added the code to set the visibility based on the SelectedItem of ComboBox1 and set ItemsSource based on the SelectedItem of ComboBox1.

Things to do in ViewModel.

  1. Have a property which bind to the SelectedItem of ComboBox1.
  2. Have a collection property which need to be bound to the ComboBox2 based on the SelectedItem of ComboBox1.
  3. Whenever the SelectedItemCombo1 is changes, update the collection property bound to the ItemsSource of ComboBox2 (you can do it at the PropertyChanged event of SelectedItem of Combo1, else you can write a command for SelectionChanged in VM)

Find the XAML code for ComboBox2, I have added converter to check for the SelectedItem of ComboBox1, if it is null, the ComboBox2 will not be visible.

<ComboBox Name="Re" Grid.Row="2" Grid.Column="1" VerticalAlignment="Top"  ItemsSoure="{Binding combo1Selected}"
    Visibility="{Binding ElementName=PL, Path=SelectedItem, Converter={StaticResource selectedItemToVisibilityConverter}}"> />

Converter as follows:

public class SelectedItemToVisibility : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return Visibility.Collapsed;
            else
                return Visibility.Visible;
        }

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

Hope this helps you.

Karuppasamy
  • 206
  • 1
  • 7