我的客户端在Windows应用中遇到DataGridView问题。他们正在调用CellValidated事件,但是如果它已经提交回数据源,那么他们希望对单元格进行不同的验证,而不是首先添加(并且尚未提交)的行(用户)还没有离开行。)我尝试了IsNewRow属性,但是一旦你开始输入行,就会添加另一个“新行”,所以你正在使用的行不再被认为是新行。知道该行尚未提交,因为您可以点击Esc取消编辑,整个行都会消失。
有没有办法判断当前编辑的行是否实际上是“新行”,因为它尚未提交回数据源?
答案 0 :(得分:3)
我过去实现类似功能的一种方法是利用绑定到列表的对象的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提供一个新行时,它的id为0(整数的默认值)。
来自数据库的每个对象都具有非零ID。
也许有一种方法可以使用BindingSources实现这一点,但我快速查看了那里的属性,没有任何东西跳出来。
答案 1 :(得分:3)
在这种情况下,数据源是什么?
如果它是数据表,那么您可以轻松地测试数据表行的DataRowState属性,以查看它们是新的还是现有的。 一旦验证了数据行,就可以调用表上的Accept来提交这些行。 在这种情况下,无需干扰网格和数据表。
当然,这并不意味着您的数据实际上已提交到数据库,如果它最终存储在数据库中。那将是另一个步骤。
另外,我通常避免直接写入datagridview;相反,我将它设为只读并弹出一个添加/输入屏幕,可以执行任何所需的验证。
我不知道这些是否对您有用 - 如果我错过了这一点,请告诉我。
答案 2 :(得分:1)
这应该可以帮助那些没有使用DataTable对象的人:
在CellBeginEdit事件中,将Tag属性设置为某个值,用于区分“新”行
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
}
答案 3 :(得分:0)
GenericMeatUnit的回答对我不起作用,但它为我提供了足够的方法来找到一种方法来使它工作。以下是我现在正在进行检查的方式:
if (this.DATASET.DATATABLE.Rows.Count == e.RowIndex)
这个if语句有效,因为在DataGridView中保留行之前,它实际上并不存在于数据表中,因此数据表中的行数将等于新行的RowIndex,因为RowIndex为零基