Установка выбранного элемента в ListBox без зацикливания

У меня есть список с множественным выбором, который я привязываю к DataTable. DataTable содержит 2 столбца: описание и значение.

Вот код заполнения списка:

DataTable copytable = null;
                copytable = GlobalTable.Copy(); // GlobalTable is a DataTable
                copytable.Rows[0][0] = "--ALL--";
                copytable.Rows[0][1] = "--ALL--";

                breakTypeList.DataSource = copytable;
                this.breakTypeList.DisplayMember = copytable.Columns[0].ColumnName; // description
                this.breakTypeList.ValueMember = copytable.Columns[1].ColumnName; // value
                this.breakTypeList.SelectedIndex = -1;

Я устанавливаю описание как DisplayMember, а значение как ValueMember ListBox. Теперь, в зависимости от того, какое значение передано, мне нужно установить выбранный элемент в ListBox.

Вот мой код:

ListBox lb = c as ListBox;
lb.SelectedValue = valuePassedByUser;

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

for (int i = 0; i < lb.Items.Count; i++)
            {
                DataRowView dr = lb.Items[i] as DataRowView;
                if (dr["value"].ToString() == valuePassedByUser)
                {
                    lb.SelectedIndices.Add(i);
                    break;
                }
            }

Я хотел бы знать, что отсутствует / ошибочно в моем коде. Почему lb.SelectedValue = valuePassedByUser; выбираете неправильные позиции?


person SO User    schedule 18.05.2009    source источник
comment
Не могли бы вы дать дополнительную информацию о том, что именно вам нужно сделать, или более полный пример кода? Должен ли объект читать поле из базы данных и устанавливать для выбранного индекса / значения соответствующее значение в списке?   -  person ryanulit    schedule 18.05.2009
comment
Список заполняется таблицей данных, которая, в свою очередь, содержит данные, полученные из базы данных. Меня беспокоит, что если я установил ValueMember при заполнении списка, почему lb.SelectedValue = valuePassedByUser; не работает?   -  person SO User    schedule 03.06.2009


Ответы (6)


Хорошо ... вот и трудный для переваривания ответ, который я понял только вчера. Это моя ошибка, что я не упомянул одну важную вещь в своем вопросе, потому что я чувствовал, что это не имеет отношения к рассматриваемой проблеме:

Данные в таблице данных не отсортированы. Следовательно, я установил для свойства Sorted списка значение true. Позже я понял, что когда свойство сортировки списка или даже поля со списком имеет значение true, тогда член значения не устанавливается должным образом. Итак, если я напишу:

lb.SelectedValue = valuePassedByUser;

он устанавливает какой-то другой элемент как выбранный, а не устанавливает значение, значение которого равно valuePassedByUser. Короче это портит индексы.

Например, если мои исходные данные:

Index   ValueMember DisplayMember
1          A            Apple
2          M            Mango
3          O            Orange
4          B            Banana

И я установил sorted = true. Тогда элементы списка:

Index   ValueMember DisplayMember
1          A            Apple
2          B            Banana
3          M            Mango
4          O            Orange

Теперь, если я хочу установить Banana как выбранный, я запускаю stmt:

lb.SelectedValue = "B";

Но вместо того, чтобы установить Banana как выбранный, он устанавливает Orange как выбранный. Почему? Поскольку, если бы список не был отсортирован, индекс банана был бы равен 4. Таким образом, даже если после сортировки индекса банана равняется 2, он устанавливает индекс 4 как выбранный, тем самым делая выбранным апельсин вместо банана.

Следовательно, для отсортированного списка я использую следующий код для установки выбранных элементов:

private void SetSelectedBreakType(ListBox lb, string value)
{
    for (int i = 0; i < lb.Items.Count; i++)
    {
        DataRowView dr = lb.Items[i] as DataRowView;
        if (dr["value"].ToString() == value)
        {
            lb.SelectedIndices.Add(i);
            break;
        }
    }
}
person SO User    schedule 14.07.2009

Я думаю, что единственный способ выбрать несколько элементов - это использовать цикл foreach. Кажется, что свойство SelectedValue возвращает только 1 элемент. Если вы хотите выбрать более 1 элемента, вам придется использовать:

var tempListBox = c As ListBox;
if (tempListBox != null)
     (tempListBox.SelectedItems.Add(tempListBox.Items[tempListBox.FindStringExact(fieldValue)]);

Кроме того, FindStringExact не выполняет поиск в полях значений, а только просматривает отображаемый текст. Кроме того, для сокращения кода может потребоваться преобразовать новую переменную в список, чтобы не преобразовывать C в список.

person norlando    schedule 18.05.2009

Попробуй это:-

 var listBox = c as ListBox;
    var item = listBox.Items.FindByValue(fieldValue);
    if (item != null)
     listBox.SelectedValue = fieldValue;
person scorpio    schedule 18.05.2009
comment
В коллекции Items нет FindByValue. - person norlando; 18.05.2009

Вы можете использовать FindByValue следующим образом:

ListBox.SelectedIndex = ListBox.Items.IndexOf(ListBox.Items.FindByValue(fieldValue))
person idleMind    schedule 02.08.2010

Вот как я это решил, используя winforms, DotNet 4.6

listBox1.SelectedIndex = listBox1.FindString(stringInList);
person Ben Winding    schedule 17.08.2016

Если вы не хотите зацикливаться для выбранных элементов, извлеките выбранное значение поля списка из события listBox_SelectedIndexChanged и добавьте это значение в глобальный массив. Затем, получив доступ к этому массиву, вы получите желаемое значение выбранных элементов itemlist без какого-либо цикла.

person MuhammadWaseem    schedule 17.08.2016