Я использую DataGridView
в приложении C#
WinForms
и хочу, чтобы пользователь выбирал между набором значений, которые будут одинаковыми в каждой ячейке. Я предполагаю, что должен быть способ заполнить все ячейки списком значений.Как заполнить DataGridViewCombobBoxColumn со значениями
Используя графический дизайнер, я добавил COL_BUSINESS_INDUSTRY
, что является DataGridViewComboBoxColumn
в DataGridView. В конструкторе, я хочу, чтобы заполнить ComboBoxes со списком значений, для которых я использую следующий код:
COL_BUSINESS_INDUSTRY.DataSource = LoadIndustries();
COL_BUSINESS_INDUSTRY.DataPropertyName = "industryName";
COL_BUSINESS_INDUSTRY.DisplayMember = COL_BUSINESS_INDUSTRY.DataPropertyName;
COL_BUSINESS_INDUSTRY.ValueMember = COL_BUSINESS_INDUSTRY.DataPropertyName;
LoadIndustries()
возвращает DataTable
, который имеет два fiels: id
и industryName
The проблема в том, что когда я выполняю это, ComboBoxes не содержит значений.
Я также попробовал LoadIndustries()
вернуть List<string>
, не установив DataPropertyName
, но это тоже не сработало.
Я также попытался сделать это, с LoadIndustries()
возвращающая List<string>
, но все-таки не повезло:
COL_BUSINESS_INDUSTRY.Items.AddRange();
Очевидно, что я делаю что-то неправильно, но это было более 3 часов на поиск в Интернете, и я понятия не имею. Почему мои ComboBoxes не отображают значения?
EDIT: По предложению TAW, я сделал следующие изменения, которые до сих пор не работают:
Добавлен следующий класс содержит следующие значения:
class IndustryObj
{
public string theString { get; set; }
public string theId { get; set; }
public IndustryObj(string id, string s) { theId = id; theString = s; }
public override string ToString() { return theString; }
}
Я нахожусь загружая отрасли следующим образом. Я могу гарантировать, что загрузка значений в объектах работает отлично:
private static List<IndustryObj> LoadIndustries()
{
var industries = new List<IndustryObj>();
const string sql = "SELECT id, name FROM Industry ORDER BY name";
using (var sqlQuery = new CustomSqlQuery(MyDatabases.Telemarketing, sql))
{
foreach (var record in sqlQuery)
{
industries.Add(new IndustryObj(record[0].ToString(), record[1].ToString()));
}
}
return industries;
}
Это метод, где я заполнение DataGridView. Все значения загружаются в порядке, за исключением тех, за исключением COL_BUSINESS_INDUSTRY
:
private void LoadBusinesses()
{
COL_BUSINESS_INDUSTRY.DataSource = LoadIndustries();
COL_BUSINESS_INDUSTRY.DataPropertyName = "theString";
COL_BUSINESS_INDUSTRY.DisplayMember = COL_BUSINESS_INDUSTRY.DataPropertyName;
COL_BUSINESS_INDUSTRY.ValueMember = "theId";
const string sql = "SELECT id, company, contact, address, phone, email, status, industry, callbackDate, callbackTime, createdBy, lastUpdatedBy, lockedUntil FROM Business ORDER BY company";
using (var sqlQuery = new CustomSqlQuery(MyDatabases.Telemarketing, sql))
{
var columns = new DataGridViewColumn[]
{
COL_BUSINESS_COMPANY,
COL_BUSINESS_CONTACT,
COL_BUSINESS_ADDRESS,
COL_BUSINESS_PHONE,
COL_BUSINESS_EMAIL,
COL_BUSINESS_STATUS,
COL_BUSINESS_INDUSTRY,
COL_BUSINESS_CALLBACKDATE,
COL_BUSINESS_CALLBACKTIME,
COL_BUSINESS_CREATEDBY,
COL_BUSINESS_LASTUPDATEDBY,
COL_BUSINESS_LOCKEDUNTIL
};
foreach (var record in sqlQuery)
{
dgv_Businesses.Rows.Add(CustomDGVRow.InitializeFromDataReader(true, record, columns));
}
}
}
EDIT 2: После второго предложения TAW, я сделал следующее. Это не помогло:
private List<IndustryObj> industryObjects;
private void LoadBusinesses()
{
industryObjects = LoadIndustries();
COL_BUSINESS_INDUSTRY.DataSource = industryObjects;
COL_BUSINESS_INDUSTRY.DataPropertyName = "theString";
COL_BUSINESS_INDUSTRY.DisplayMember = COL_BUSINESS_INDUSTRY.DataPropertyName;
COL_BUSINESS_INDUSTRY.ValueMember = "theId";
...
EDIT 3: Luminous
на самом деле есть, но что вводит ряд других проблем. Метод загрузки теперь выглядит следующим образом:
private void LoadBusinesses()
{
// Load the records.
const string sql =
"SELECT id, company, contact, address, phone, email, status, industry, callbackDate, callbackTime, createdBy, lastUpdatedBy, lockedUntil FROM Business ORDER BY company";
using (var sqlQuery = new CustomSqlQuery(MyDatabases.Telemarketing, sql))
{
var columns = new DataGridViewColumn[]
{
COL_BUSINESS_COMPANY,
COL_BUSINESS_CONTACT,
COL_BUSINESS_ADDRESS,
COL_BUSINESS_PHONE,
COL_BUSINESS_EMAIL,
COL_BUSINESS_STATUS,
COL_BUSINESS_INDUSTRY,
COL_BUSINESS_CALLBACKDATE,
COL_BUSINESS_CALLBACKTIME,
COL_BUSINESS_CREATEDBY,
COL_BUSINESS_LASTUPDATEDBY,
COL_BUSINESS_LOCKEDUNTIL
};
foreach (var record in sqlQuery)
{
dgv_Businesses.Rows.Add(CustomDGVRow.InitializeFromDataReader(true, record, columns));
}
}
// Load the industries and bind the industry DataSource to the industry ComboBoxColumn.
COL_BUSINESS_INDUSTRY.DataSource = LoadIndustries();
COL_BUSINESS_INDUSTRY.DataPropertyName = "theString";
COL_BUSINESS_INDUSTRY.DisplayMember = COL_BUSINESS_INDUSTRY.DataPropertyName;
COL_BUSINESS_INDUSTRY.ValueMember = "theId";
// Select the correct industries in the industry column.
foreach (var rawRow in dgv_Businesses.Rows)
{
var row = rawRow as CustomDGVRow;
if (row == null) continue;
foreach (var item in ((CustomDGVComboBoxCell) row.Cells[COL_BUSINESS_INDUSTRY.Index]).Items)
{
var industry = item as IndustryObj;
if (industry == null) continue;
if (row.Cells[COL_BUSINESS_INDUSTRY.Index].Value != null && industry.theId == row.Cells[COL_BUSINESS_INDUSTRY.Index].Value.ToString())
{
row.Cells[COL_BUSINESS_INDUSTRY.Index].Value = industry;
}
}
}
}
Как вы можете видеть, я также необходимо выбрать одно значение из списка элементов, на основе его идентификатора в базе данных. Поскольку я привязываю только источник данных после загрузки элементов (согласно предложению Luminous
), мне нужно сделать еще один проход через строки и установить правильное отраслевое значение для каждой строки. Однако, поскольку у меня огромное количество строк, это очень дорого.Поэтому для того, чтобы наградить Баунти, мне нужен ответ на еще два вопроса:
- Как я могу не делать еще один проход, чтобы установить правильные значения?
- Зачем мне сначала загружать строки и только потом связывать источник данных? Это кажется довольно неинтуитивным, и это вызывает мою проблему. Что делать, если требования требуют, чтобы больше данных загружалось в какой-то момент после начальной загрузки? Должен ли я затем снова сделать привязку?
_COL_BUSINESS_INDUSTRY.DataSource = LoadIndustries(); _ компилировать ли это ?? Попробуйте поместить его в переменную и установите источник данных для этой переменной; Я не могу себе представить, как система может работать с DataSource, который нужно вытаскивать из функции все время. – TaW
Он компилируется без каких-либо ошибок или предупреждений. Я пробовал это, как вы можете видеть в последнем правлении, до сих пор не повезло. Любые другие идеи? Я также открыл щедрость для этого, поскольку мне нужно, чтобы он работал как можно скорее. –
Нет смысла загружать строки перед выпадающим столбцом, imo. вся суть этого типа столбца - позволить безопасный ввод и редактирование ценности. должно быть что-то еще неправильно. – TaW