C# DataGridView добавление строки-при проверке как узнать, что строка новая и еще не зафиксирована?

У меня есть клиент, имеющий проблему с DataGridView в приложении Windows. Они вызывают событие CellValidated, но они хотят иметь другую проверку для ячейки, если она находится в строке, которая уже зафиксирована обратно в источник данных, чем если это строка, которая сначала добавляется (и еще не зафиксирована (пользователь еще не покинул строку). Я попробовал свойство IsNewRow, но как только вы начинаете вводить строку, добавляется еще одна "новая строка" , поэтому строка, с которой вы работаете, не дольше рассматривал новый ряд. Я знаю, что строка еще не была зафиксирована, потому что вы можете нажать Esc, чтобы отменить редактирование, и вся строка исчезнет.

есть ли способ узнать, является ли текущая отредактированная строка фактически "новой строкой" в том смысле, что она не была зафиксирована обратно в источник данных?

4 ответов


один из способов, которым я достиг чего-то подобного в прошлом, - использовать свойство id моих объектов, привязанных к списку.

например, если у меня есть BindingList<User> где пользователь что-то вроде:

public class Names
{
    public string Name { get; set; }         
    public int id { get; set; }
}

затем я могу связать свой список следующим образом:

dataGridView1.AutoGenerateColumns = false;
_users = new BindingList<User>();
_users .Add(new Names() { Name = "joe", id=1 });
_users .Add(new Names() { Name = "pete", id = 2 });

bindingSource1.DataSource = _names;

DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.DataPropertyName = "Name";        

dataGridView1.Columns.Add(col1);

dataGridView1.DataSource = _users;

затем, когда DataGridView предоставляет новую строку, она будет иметь идентификатор 0 (значение по умолчанию для целого числа).

каждый объект, который поступает из базы данных, имеет ненулевое значение идентификатор.

также может быть способ достичь этого с помощью BindingSources, но я быстро просмотрел свойства там, и ничего не выскочило на меня.


Что такое источник данных в этом случае?

Если это datatable, то вы можете легко проверить свойство DataRowState строк datatable, чтобы увидеть, являются ли они новыми или существующими. После проверки ваших потоков данных вы можете вызвать Accept в таблице для фиксации этих строк. В этой ситуации нет необходимости вмешиваться между сеткой и datatable.

конечно, это не означает, что ваши данные в базу данных, если это наконец-то хранится. Это будет еще один шаг.

кроме того, я обычно избегаю прямой записи в datagridview; вместо этого я делаю его доступным только для чтения и всплываю экран добавления/ввода, который может выполнять любую требуемую проверку.

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


ответ GenericMeatUnit не работал для меня, но он предоставил мне достаточно, чтобы найти способ заставить его работать. Вот как я делаю проверку так:

if (this.DATASET.DATATABLE.Rows.Count == e.RowIndex)

Это оператор if работает, потому что перед выходом строки в DataGridView она еще не существует в datatable, поэтому количество строк в datatable будет равно RowIndex для новой строки, так как RowIndex основан на нуле.


Это должно помочь людям, которые не используют объекты DataTable:

в событии CellBeginEdit присвойте свойству Tag некоторое значение, которое будет использоваться для дифференциации строки "new"

private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
    if (e.RowIndex == dataGridView1.NewRowIndex)
        dataGridView1.Rows[e.RowIndex].Tag = true;
}

затем в вашем событии проверки вы можете проверить это значение:

if (dataGridView1.Rows[e.RowIndex].Tag is bool 
    && (bool) dataGridView1.Rows[e.RowIndex].Tag)
{
    // new row code

    // after it's added, mark it as 'not new'
    dataGridView1.Rows[e.RowIndex].Tag = false;
}
else
{
    // existing row code
}