-1

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:\Users\Client 0819\source\repos\Cyanair\cyanair.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:\Users\Client 0819\source\repos\Cyanair\cyanair.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 :)

  • So, what's the question? Is there something about the code you've posted that isn't working? If so, what isn't working? Is an exception being thrown? `comboArrival` isn't populated? `comboArrival` doesn't filter? – Joshua Robinson Feb 06 '20 at 15:29
  • used if condition and comboBox1.SelectedIndex = comboBox2.SelectedIndex; then true don't submit application – Malakiya sanjay Feb 06 '20 at 15:30
  • 1
    Just use a filter on the datasource rather than running a new query everytime. And never, ever concat data into a string for a query – Ňɏssa Pøngjǣrdenlarp Feb 06 '20 at 15:32
  • @JoshuaRobinson comboArrival IS being populated, but it doesn't filter the result. If for example 'London' is chosen in comboDeparture I would like for London to not appear as an option in comboArrival. Both comboBoxes are using the same table of locations. – Daragh Walker Feb 07 '20 at 12:20

1 Answers1

0

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;
}
Joshua Robinson
  • 3,399
  • 7
  • 22