Как выбрать элемент из выпадающего списка по ключу? - PullRequest
0 голосов
/ 02 июля 2019

Я заполняю comboBox, получая данные из базы данных

Это моя структура базы данных:

Table names

ID ------ Name

1  ------ John
2  ------ Sarah
3  ------ Peter

Это моя структура класса

// Class structure

    public class Names
    {
        public int id;
        public string name;
    }

Вот какЯ объявляю свой словарь и как я его устанавливаю

// Declare dictionary
Dictionary<int, string> dataSouceNames;

public MyProgram()
{
    InitializeComponent();
    dataSouceNames = getComboDataSourceNames();
}

//Dictionary
private Dictionary<int, string> getComboDataSourceNames()
{
    Dictionary<int,string> comboSource = new Dictionary<int,string>();

    List<Names> res = dataProvider.getAllNames();

    foreach (Names item in res)
    {
        comboSource.Add(item.id, item.nome);
    }

    return comboSource;
}

Это SQL, который я использовал для получения данных из базы данных

getAllNames()
{
    string sql = "SELECT * FROM names";
}

В конце, как язаполните мой ComboBox

// Function fill combobox
private void initComboNames()
{
    cmbNames.DataSource = new BindingSource(dataSourceNames, null);
    cmbNames.DisplayMember = "Text";
    cmbNames.ValueMember = "Value";
}

Затем я пытаюсь выбрать элемент в выпадающем списке по ключу:

    cmbNames.SelectedItem = Names.ID // WHERE Names.ID is number "2"

Я ожидал, что вывод "Сара" как SelectedIndex, но я знаю, что я делаю это неправильно.

Ответы [ 3 ]

0 голосов
/ 02 июля 2019

Сначала вы заполняете комбинированный список таким способом. при этом comboBox покажет имя (Показать элемент) пользователю, но когда вы выберете индекс, вы получите идентификатор (значение элемента)

SQL.con.Open();
DataTable tb = new DataTable();
SqlCommand cmd = new SqlCommand("select columnID,Name from TableName",SQL.con);
SqlDataReader dr;
dr = cmb.ExecuteReader();
tb.Load(dr);
comboBox.DisplayMember = "Name";
comboBox.ValueMember = "columnID";
comboBox.DataSource = tb; 

Когда вы закончите с этим, вы можете просто получить идентификатор по

int id =  comboBox.SelectedValue;

Помните об изменении полей, таких как comboboc, columnId и т. Д. С вашим полем желаний

0 голосов
/ 03 июля 2019

Почему я предложил использовать это назначение для установки текущего элемента ComboBox:

cmbNames.SelectedItem = new KeyValuePair<int, string>(Names.ID, dataSouceCantieri[Names.ID]);

, а также для определения DisplayMember и ValueMember свойств, подобных этому:

cmbNames.DisplayMember = "Value";
cmbNames.ValueMember = "Key";
cmbNames.DataSource = new BindingSource(dataSouceCantieri, null);

Это связано с тем, что происходит, когда вы устанавливаете [ComboBox].DataSource = [Dictionary<TKey, TValue>];.
Ну, на самом деле вы не можете этого сделать.Словарь - это сложный объект, который напрямую не управляется свойством DataSource элемента управления;он принимает только сложный объект, который реализует IList или IListSource .Словарь не.

Конечно, вы можете преобразовать словарь в список, теперь он будет принят:

[ComboBox].DataSource = [Dictionary<TKey, TValue>].ToList();

Мы предоставляем List<KeyValuePair<TKey, TValue>>, который реализует IList<T>.
Кроме того, каждый элемент списка имеет вид KeyValuePair<TKey, TValue>.
Этот объект обладает двумя свойствами: Key иValue, который позволяет получить доступ к внутренним значениям объекта.
Словарь предоставляет только коллекцию Keys и свойства Values ​​.Другие сложные объекты.

Когда вы устанавливаете BindingSource.DataSource в словарь, этот класс выполняет ту же операцию: он проверяет, реализует ли объект, который мы назначаем, реализациюIList или IListSource;в противном случае он создает новый BindingList и использует метод IEnumerable.GetEnumerator () для извлечения элементов из коллекции.
Dictionary.GetEnumerator () возвращает каждый элемент коллекции как KeyValuePair<TKey, TValue>, так же, как и вызов [Dictionary].ToList().

См. Это поведение в справочном источнике .Net:

Основной конструктор BindingSource
Список IList = [BindingSource] .GetListFromEnumerable ()
приватный статический IList CreateBindingList (Type type)

Итак, когда мы присваиваем это:

cmbNames.DataSource = new BindingSource(dataSourceNames, null);

, мы фактически устанавливаем источник данных элемента управления равным IList<KeyValuePair<TKey, TValue>>.
Как следствие, каждый ComboBox.Item является KeyValuePair<TKey, TValue>.
A KeyValuePair<int, string>, здесь.
Вот почему мы можем установить:

[ComboBox].DisplayMember = "Value";
[ComboBox].ValueMember = "Key";

это имена свойств, предоставляемых классом KeyValuePair<TKey, TValue>.

Поскольку каждый элемент ComboBox представляет собой KeyValuePair<int, string>, чтобы выбрать элемент, сделав его текущим, мы можем установить для него определенный KeyValuePair<int, string>.
В вашем случае ключпредоставлено свойством Names.ID:

cmbNames.SelectedItem = new KeyValuePair<int, string>(Names.ID, dataSouceCantieri[Names.ID]);

Я использовал эту форму: new KeyValuePair<int, string>(Names.ID, dataSouceCantieri[Names.ID]), потому что таким образом мы можем получить доступ к Словарю, dataSouceCantieri, напрямую через Key, так что это операция O(1).

Лучше, чем писать:

cmbNames.SelectedItem = dataSouceCantieri.FirstOrDefault(dict => dict.Key == Names.ID); 

или подобное.Этот метод подразумевает повторение коллекции до тех пор, пока не будет найден нужный элемент или его нет.

0 голосов
/ 02 июля 2019

Я думаю, что вы должны передать имя ("Сара" вместо идентификатора "2"), если невозможно, используйте SelectedValue.

cmbNames.SelectedValue = Names.Id;

В противном случае, если вы знаете индекс, это можно сделать

cmbNames.SelectedIndex= 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...