Исключение опции из ComboBox (2) на основе ввода первого ComboBox (1) c# - PullRequest
0 голосов
/ 06 февраля 2020

Я создаю систему бронирования авиабилетов, и у меня есть 2 поля со списком. Первый предназначен для города отправления, а второй - для города прибытия. Я хочу иметь возможность исключить выбор в первом поле со списком из второго, поскольку я не хочу, чтобы один и тот же город мог быть представлен как город отправления, так и город прибытия. Я запрашиваю названия городов из базы данных.

Вот мой код:

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);
        }
        }

Спасибо:)

1 Ответ

0 голосов
/ 07 февраля 2020

Похоже, вы обрабатываете событие DisplayMemberChanged на comboDeparture и пытаетесь обновить значения comboArrival в этом обработчике. Однако DisplayMemberChanged срабатывает только при изменении свойства DisplayMember.

DisplayMember только сообщает элементу управления, какое свойство отображать в элементе управления с привязкой к данным. Он не привязан к индексу или значению, выбранному в ComboBox. Таким образом, единственный раз, когда код для заполнения comboArrival выполняется, находится в конструкторе, когда вы устанавливаете comboDepartarture.DisplayMember. Вместо этого обработайте либо ComboBox.SelectedIndexChanged, либо ComboBox.SelectedValueChanged и задайте элементы comboArrival.

Несколько других важных моментов, которые следует помнить о вашем коде.

Во-первых, вы должны использовать параметризованный запрос при выполнении Sql операторов, а не объединять строки. Конкатенация строк во время выполнения открывает вам SQL инъекционных атак . Я не знаком с SqlLite и не могу предоставить вам пример того, как изменить ваш код, но, возможно, этот вопрос может помочь.

Во-вторых, вам не нужно повторяйте запрос каждый раз, когда вы изменяете выбранное значение в comboDeparture. Просто добавьте источник данных comboArrival в качестве поля на Form, и вы можете отфильтровать его. Например ...

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...