Skip to content
Advertisement

Eliminating an option from a ComboBox (2), based on the input of the first ComboBox (1) c#

I am creating an airline booking system and I have 2 combo boxes. The first is for Departure City and the second is for Arrival City. I want to be able to eliminate the choice in the first combo box from the second, as I don’t want the same city to be able to be submitted as both the departure and arrival city. I am querying the city names from a database.

Here is my code:

public partial class main : Form
{
    public main()
    {
        InitializeComponent();

        string connectionString = @"Base Schema Name=cyanair;data source=C:UsersClient 0819sourcereposCyanaircyanair.db";

        //Departure ComboBox
        SQLiteConnection conn = new SQLiteConnection(connectionString);
        try
        {
            conn.Open();
            SQLiteCommand cmd = new SQLiteCommand();

            cmd.Connection = conn;
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandText = "SELECT * FROM CyanairAirports";

            SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);

            DataTable dt = new DataTable();
            da.Fill(dt);
            comboDeparture.DataSource = dt;
            comboDeparture.ValueMember = "Descriptions";
            comboDeparture.DisplayMember = "Descriptions";



            conn.Close(); 
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    //Arrival ComboBox
    private void comboDeparture_DisplayMemberChanged(object sender, EventArgs e)
    {
        string connectionString = @"Base Schema Name=cyanair;data source=C:UsersClient 0819sourcereposCyanaircyanair.db";
        SQLiteConnection conn = new SQLiteConnection(connectionString);

        **String city = comboDeparture.DisplayMember;**

        try
        {
            conn.Open();
            SQLiteCommand cmd = new SQLiteCommand();


            cmd.Connection = conn;
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandText = "SELECT * FROM CyanairAirports WHERE Descriptions IS NOT '" + comboDeparture.SelectedValue.ToString() + "'";
            richTextBox1.Text = "SELECT * FROM CyanairAirports WHERE Descriptions IS NOT '" + comboDeparture.SelectedValue + "'";
            SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);

            DataTable dt = new DataTable();
            da.Fill(dt);
            comboArrival.DataSource = dt;
            comboArrival.ValueMember = "Descriptions";
            comboArrival.DisplayMember = "Descriptions";


            conn.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        }

Thanks 🙂

Advertisement

Answer

It looks like you’re handling the DisplayMemberChanged event on comboDeparture, and trying to update the values of comboArrival in that handler. However, DisplayMemberChanged only triggers when the DisplayMember property changes.

DisplayMember only tells the control which property to display on a data bound control. It isn’t tied to the index or value selected in the ComboBox. So, the only time the code to populate comboArrival runs is in the constructor when you set comboDepartarture.DisplayMember. Instead, handle either ComboBox.SelectedIndexChanged or ComboBox.SelectedValueChanged and set the items of comboArrival.

A few other important things to note about your code.

First, you should use a parameterized query when running Sql Statements, rather than concatenating strings. Concatenating strings as you’re doing opens you up to SQL Injection Attacks. I’m not familiar with SqlLite and can’t provide you with an example of how to modify your code, but perhaps this question can help.

Second, you don’t need to re-run the query every time you change the selected value in comboDeparture. Just add comboArrival‘s data source as a field on the Form and you can filter it. For example…

public partial class main : Form
{
   // Your constructors...

   private void comboDepartures_SelectedIndexChanged(object sender, EventArgs e)
   {
      if (_arrivalsDataSource == null)
      {
          _arrivalsDataSource = new System.Data.DataTable();
          // Load _arrivalsDataSource from the database, basically how you're doing it now.
          comboArrival.DataSource = _arrivalsDataSource.DefaultView;
          comboArrival.DisplayMember = "Descriptions"
          comboArribal.ValueMember = "Descriptions"
      }
      if (comboDeparture.SelectedIndex == -1)
      {
          _arrivalsDataSource.DefaultView.RowFilter = null; // Clear the filter.
      }
      else
      {
          // Set the filter.
          _arrivalsDataSource.DefaultView.RowFilter = $"Description <> '{comboDeparture.SelectedValue}'";
      }
   }

   private System.Data.DataTable _arrivalsDataSource = null;
}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement