2
votes

I have an event for a ComboBox, "SelectionChange".

Here's what I'm trying to do:

  1. I have two ComboBoxes
  2. The second ComboBox will display items depending on the selected item on the first Box
  3. ComboBox2 should react as soon as an item on ComboBox1 is selected

My problem is when I'm trying to get the SelectedIndex.

When I use ComboBox1.Text after confirming the SelectedIndex, it returns null so the ComboBox2 doesn't react.

I tried placing a button to force the event and it did work. It seems that the SelectedIndex doesn't change until you release focus.

Here's a snippet of the code:

if (cb_subj.SelectedIndex == ctr)
{
     cb_section.Items.Clear();
     if (connectToDB.openConnection() == true)
     {
         MySqlDataAdapter comboBoxItems_seclist = new MySqlDataAdapter();

         MySqlCommand query = new MySqlCommand(@"SELECT section_code FROM sections 
                             WHERE subject = @subj", connectToDB.connection);
         query.Parameters.AddWithValue("@subj", cb_subj.Text);

         comboBoxItems_seclist.SelectCommand = query;


         System.Data.DataTable classlist = new System.Data.DataTable();

         comboBoxItems_seclist.Fill(classlist);

         foreach (System.Data.DataRow row in classlist.Rows)
         {
            string rows = string.Format("{0}", row.ItemArray[0]);
            cb_section.Items.Add(rows);
         }
       }

      break;
}

Here's the XAML of the two CB:

<ComboBox Height="23" HorizontalAlignment="Left" Margin="166,12,0,0" Name="cbox_year" VerticalAlignment="Top" Width="120" SelectionChanged="cbox_year_SelectionChanged">
        <ComboBoxItem Content="1st Year / 1st Sem" />
        <ComboBoxItem Content="1st Year / 2nd Sem" />
        <ComboBoxItem Content="2nd Year / 1st Sem" />
        <ComboBoxItem Content="2nd Year / 2nd Sem" />
        <ComboBoxItem Content="3rd Year / 1st Sem" />
        <ComboBoxItem Content="3rd Year / 2nd Sem" />
        <ComboBoxItem Content="4th Year / 1st Sem" />
        <ComboBoxItem Content="4th Year / 2nd Sem" />
    </ComboBox>
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="166,41,0,0" Name="cb_subj" VerticalAlignment="Top" Width="120" SelectionChanged="cb_subj_SelectionChanged" />
3
Can you post the relevant XAML? Also, what event handler is your code part of?Erik Dietrich
It's part of the SelectionChanged event for the BoxesNathan

3 Answers

3
votes

For a quick success, you could access ComboBox1.SelectedValue or ComboBox1.SelectedItem instead of ComboBox1.Text.

Your main problem seems to be that when selection changes in ComboBox1, it does not directly change the ComboBox1.Text, you (i.e. the focus) will have to leave ComboBox1 until the Text is updated. Typically, you can avoid such problems by using databinding instead of this eventbased approach.

1
votes

It doesn't seem like used binding? I would recommend to use binding and then turn the UpdateSourceTrigger property of the binding to UpdateSourceTrigger.PropertyChanged

In the underlaying object u can then listen to a propertychanged event, but be sure to implement INotifyPropertyChanged.

For an example look at http://www.tanguay.info/web/index.php?pg=codeExamples&id=304

In a bit more detail:

In the view make sure u set the DataContext and populate year collection Also impliment the INotifyPropertyChanged

For one combobox this and for the other it's almost the same.

    private ObservableCollection<KeyValuePair<string, string>> _yearValues = new   ObservableCollection<KeyValuePair<string, string>>();
    public ObservableCollection<KeyValuePair<string, string>> YearValues
    {
        get
        {
            return _yearValues;
        }

        set
        {
            _yearDownValues = value;
            OnPropertyChanged("YearValues");
        }
    }

    private string _selectedYear;
    public string SelectedYear
    {
        get
        {
            return _selectedYear;
        }

        set
        {
            _selectedYear = value;
            OnPropertyChanged("SelectedYear");
        }
    }

Be sure to hook the OnPropertyChanged and do your thing

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (propertyName == "SelectedYear")
        {
            // populate subj collection which will update the combobox
        }
    }

In your xaml:

<ComboBox Name="YearCombobox" 
        ItemsSource="{Binding YearValues}"
        SelectedValue="{Binding SelectedYear}"
        SelectedValuePath="Key"
        DisplayMemberPath="Value"/>
<ComboBox Name="SubjCombobox" 
        ItemsSource="{Binding SubjValues}"
        SelectedValue="{Binding SelectedSubj}"
        SelectedValuePath="Key"
        DisplayMemberPath="Value"/>
0
votes

Did you try

e.AddedItems[0]

It seems if you are not using MVVM (which you should generally) sometimes the SelectionChanged does get to null. Choose this instead of the others.

Try

var selectionItem = e.AddedItems[0] as ComboBoxItem;
string text = selectionItem.Content.ToString();

The e.RemovedItems can also be used to get the previously selected item.