Pull to refresh

Зловредное «Недопустимое значение DataGridViewComboBoxCell» в vb.net и c#

Reading time 2 min
Views 3.6K
Привет всем, программирующим окошки под MS VS.

Проблема


1. Есть DataGridView, один из столбцов — DataGridViewComboBoxColumn;
2. Данные в грид закидываются через DataSource, как DataTable (не построчно, это важно);
3. Данные в ComboBoxColumn тоже биндятся, в источнике данных есть заполненный DataMember, построчно или нет — не важно, конкретная структура данных тоже не важна, ValueMember в ней Integer, Long или даже String.

При выборе чего-то из выпадающего списка dgv_DataError ловит ошибку: «Недопустимое значение DataGridViewComboBoxCell». И на заполнении — ее же.

Поиски


Гугл выдал всего две с половиной страницы форумов. Значит, проблема распространена, но на среднем уровне не решается. Неверные направления развития мысли:
а) После привязывания данных пройтись по каждой строке и ручками переназначить значение в ячейке, найдя его в списке.
б) Повесить обработку dgv_DataError.

В то же время при ручном заполнении строк в таблице через Rows.Add() все хорошо.

Мои коллеги по несчастью пытались разобраться, что не так со списком, но проблема оказалась не в нем, а именно что в несоответствии типов.

Так исторически сложилось, что в MS SQL для столбца с включенным Identity используется decimal. Да, это decimal (18,0), но он все равно остается дробным типом данных. Согласен, всегда удобно видеть десятичную разрядность индекса. Если у меня ожидается до миллиона записей в год, то decimal (7,0) хватит на 10 лет, а decimal (10,0) на 10000. Допустим, Солнце взорвется через 5 миллиардов лет — посчитаем разряды: 6+9, то есть хватит и decimal (15,0), а уж дефолтных 18 — с запасом.

А в списке-то у нас Integer, Long или даже String!

Заполняй мы строки ручками, железный болван за нас неявно все дробное и недробное преобразует. Медленно и надежно. А мы хотим быстро, но экономия достигается в том числе и на отсутствии лишних проверок типов и преобразований.

В результате же мы получаем две проблемы:
1. При загрузке данных в таблицу вместо заголовочных названий из списка в столбец выводятся айдишники из базы.
2. При выборе заголовочного названия из выпадающего списка значение в ячейке не обновляется.

Решение


Если база очень-очень большая, старая, либо недоступна для разработчика интерфейса — использовать decimal индексы в комбобоксе.

Если проще поменять структуру таблиц в базе, то использовать для внешних ключей bigint — благо, он больше decimal (18,0) почти на целый разряд и быстрее.
Tags:
Hubs:
+4
Comments 0
Comments Leave a comment

Articles