Как установить значение ячейки DataGridViewRow по имени столбца?

В формах Windows я пытаюсь заполнить DataGridView вручную, вставив в него DataGridViewRows, поэтому мой код выглядит так:

DataGridViewRow row = new DataGridViewRow();
row.CreateCells(dgvArticles);
row.Cells[0].Value = product.Id;
row.Cells[1].Value = product.Description;
.
.
.
dgvArticles.Rows.Add(row);

Однако я хотел бы добавить значение Cell по имени столбца, а не по индексу, например:

row.Cells["code"].Value = product.Id;
row.Cells["description"].Value = product.Description;

Но при таком выполнении выдается ошибка о том, что не удалось найти столбец с именем «код». Я устанавливаю столбцы DataGridView из дизайнера следующим образом: Columns from DataGridViewDesigner

Я делаю что-то неправильно? Как я могу выполнить то, что я хочу сделать?


person Community    schedule 02.03.2014    source источник


Ответы (5)


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

//Create the new row first and get the index of the new row
int rowIndex = this.dataGridView1.Rows.Add();

//Obtain a reference to the newly created DataGridViewRow 
var row = this.dataGridView1.Rows[rowIndex];

//Now this won't fail since the row and columns exist 
row.Cells["code"].Value = product.Id;
row.Cells["description"].Value = product.Description;
person Derek W    schedule 02.03.2014
comment
row.Cells[code].Value следует изменить как row.Cells[Code].Value, первая буква заглавная. Или row.Cells[code.Name].Value, первая буква в нижнем регистре. - person Bravo Yeung; 14.12.2018
comment
@BravoYeung: согласно снимку экрана, предоставленному OP: для свойства Name установлено значение code (нижний регистр), а для свойства HeaderText установлено значение Code (верхний регистр). В этом случае вам нужно ссылаться на столбец Name, а не на HeaderText через индексатор. - person Derek W; 04.02.2019

Я тоже попробовал и получил тот же результат. Это немного многословно, но работает:

row.Cells[dataGridView1.Columns["code"].Index].Value = product.Id;
person Grant Winney    schedule 02.03.2014
comment
row.Cells[code].Value следует изменить как row.Cells[Code].Value, первая буква заглавная. Или row.Cells[code.Name].Value, первая буква в нижнем регистре. - person Bravo Yeung; 14.12.2018

Когда вы используете индексатор ColumnName для DataGridViewCellCollection, внутри он пытается получить индекс столбца, используя ColumnName от владельца/родителя DataGridView этого экземпляра DataGridViewRow. В вашем случае строка не была добавлена ​​в DataGridView, и, следовательно, владение DataGridView равно null. Вот почему вы получаете сообщение об ошибке Не удалось найти столбец с именем code.

IMO лучший подход (такой же, как у Дерека) состоял бы в том, чтобы добавить строку в DataGridView и использовать возвращенный индекс для получения экземпляра строки из сетки, а затем использовать имя столбца для доступа к ячейкам.

person Junaith    schedule 02.03.2014

Проблема в том, что ссылки на ячейки по имени не работают, пока строка не будет добавлена ​​в DataGridView. Внутри он использует свойство DataGridViewRow.DataGridView для получения имен столбцов, но это свойство имеет значение null, пока не будет добавлена ​​строка.

Используя локальную функцию C# 7.0, код можно сделать наполовину читаемым.

DataGridViewRow row = new DataGridViewRow();
row.CreateCells(dgvArticles);

DataGridViewCell CellByName(string columnName)
{
    var column = dgvArticles.Columns[columnName];
    if (column == null)
        throw new InvalidOperationException("Unknown column name: " + columnName);
    return row.Cells[column.Index];
}


CellByName("code").Value = product.Id;
CellByName("description").Value = product.Description;
.
.
.
dgvArticles.Rows.Add(row);
person Timothy Klenke    schedule 23.04.2018

Другой вариант:
предположим, что имя вашего DataGridView — dataGridView1.

var row = new DataGridViewRow();
// Initialize Cells for this row
row.CreateCells(_dataGridViewLotSelection);

// Set values
row.Cells[dataGridView1.Columns.IndexOf(code)].Value = product.Id;
row.Cells[dataGridView1.Columns.IndexOf(description)].Value = product.Description;
// Add this row to DataGridView
dataGridView1.Rows.Add(row);
person Bravo Yeung    schedule 14.12.2018