Hashain Fernando Ответов: 1

Как создать два поля со списком, которые зависят друг от друга в C#?


В моем приложении windows form есть два поля со списком. 1-й - это код бренда, а 2-й - название бренда. Я загружаю все данные в оба поля со списком при загрузке формы. Когда я выбираю один код бренда из списка кодов, соответствующее название бренда отображается в поле со списком (2-е). Все в порядке.
Но я хочу и наоборот, так как при выборе названия бренда код бренда должен отображаться в его поле со списком.
Я использую базу данных Microsoft access.
Как реализовать оба процесса на одном интерфейсе?

Что я уже пробовал:

//form load event

private void Brands_Load(object sender, EventArgs e)
{
    try
    {
        con.Open();
        OleDbDataReader reader = null;
		OleDbCommand cmd = new OleDbCommand("Select * From Brand", con);
        reader = cmd.ExecuteReader();               
                  
        while (reader.Read())
        {

            cmbbCode.Items.Add(reader["BCODE"].ToString());
            cmbbName.Items.Add(reader["BNAME"].ToString());
        }
                
        con.Close();

    }
    catch (Exception ex)
    {
        MessageBox.Show("error " + ex);
    }
}

//cmbBcode change value event

		private void cmbbCode_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                String Bcode = cmbbCode.Text.ToString();
                con.Open();
                OleDbDataReader reader = null;
                OleDbCommand cmd = new OleDbCommand("Select BNAME From Brand Where BCODE = '" + Bcode + "'", con);
                reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    String Name = reader["BNAME"].ToString();
                    cmbbName.Text = Name;
                }
                con.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("error " + ex);
            }
        }
        }

Richard MacCutchan

Просто добавьте тот же код, что и выше, но поменяв местами поля со списком.

Hashain Fernando

не могу, потому что когда я вызываю метод cmbbCode_SelectedIndexChanged (он вызывается, когда я выбираю значение из поля со списком код бренда), метод cmbbName_SelectedIndexChanged также вызывается.

И здесь есть исключение. (соединение не закрыто).

Hashain Fernando

Ниже произошло исключение.

Система.Исключение InvalidOperationException: соединение не было закрыто. Текущее состояние соединения открыто.
в System.Data.База поставщиков.DbConnectionInternal.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
в System.Data.База поставщиков.DbConnectionInternal.Содержащие вредоносные элементы(outerConnection объекта dbConnection, connectionFactory DbConnectionFactory )
в System.Data.Oledb для.Метод oledbconnection.Открыть()
в AutoSpa_Xpress.Brands.cmbbName_SelectedIndexChanged(отправитель объекта, EventArgs e) in C:\Users\hashainf\documents\visual studio 2010\Projects\AutoSpa Xpress\AutoSpa Xpress\Brands.cs:line 211

1 Ответов

Рейтинг:
4

OriginalGriff

Я бы так не поступил. Вместо того, чтобы не использовать DateReader, использовать dataadapter и использовать .NET встроенный код для доступа к данным.
Этот код использует SQL Server вместо OleDb, но это то же самое для вашей БД - у меня есть открытые SSMS, поэтому мне проще играть с SQL Server в данный момент:

using (SqlConnection con = new SqlConnection(strConnect))
    {
    DataTable dt = new DataTable();
    using (SqlDataAdapter da = new SqlDataAdapter("Select BCODE, BNAME FROM Brand", con))
        {
        da.Fill(dt);
        cmbbCode.DataSource = dt;
        cmbbCode.DisplayMember = "BCODE";
        cmbbName.DataSource = dt;
        cmbbName.DisplayMember = "BNAME";
        cmbbCode.SelectedIndex = 0;
        }
    }
Это считывает данные из вашей БД и говорит каждому ComboBox отображать другое значение из той же записи.
Затем установите их обоих для обработки события SelectedIndexChanged с помощью одного и того же обработчика:
private void cmbBoth_SelectedIndexChanged(object sender, EventArgs e)
    {
    ComboBox cb = sender as ComboBox;
    if (cb != null && cmbbCode.DataSource != null && cmbbName.DataSource != null)
        {
        int index = cb.SelectedIndex;
        if (index >= 0)
            {
            if (cmbbCode.SelectedIndex != index) cmbbCode.SelectedIndex = index;
            if (cmbbName.SelectedIndex != index) cmbbName.SelectedIndex = index;
            }
        }
    }
Обработчик получает новый индекс из любого ComboBox, который пользователь только что изменил, и устанавливает его для них обоих. Нулевые проверки удостоверяются, что оба они уже загружены (или вы получите ошибку, что индекс находится вне диапазона), а проверки "это тот же самый индекс?" удостоверяются, что мы не получаем бесконечного цикла изменений индекса!
Попробуйте: он намного проще в использовании, чем вы думаете, и позволяет системе обрабатывать все за вас, что намного чище, чем ваше решение.


Hashain Fernando

Спасибо за вашу помощь.

OriginalGriff

Всегда пожалуйста!

Hashain Fernando

Пожалуйста, объясните, в чем разница между OleDbDataReader и OleDbDataAdaptor

OriginalGriff

Google-ваш друг: будьте любезны и часто навещайте его. Он может ответить на вопросы гораздо быстрее, чем разместить их здесь...

Очень быстрый поиск **используя Ваш вопрос в качестве поискового термина** дал 23 000 просмотров:
https://www.google.co.uk/search-что?q=what+is+the+difference+between+OleDbDataReader+and+OleDbDataAdaptor&oq=what+is+the+difference+between+OleDbDataReader+and+OleDbDataAdaptor&aqs=chrome..69i57&sourceid=chrome&ie=UTF-8

В будущем, пожалуйста, постарайтесь провести хотя бы фундаментальные исследования самостоятельно, а не тратить впустую свое или наше время.