我不同意你的评论……
”绑定对象的属性获取之前的新值
CellValidating 可以。” …
在执行“离开”网格CellValidating 事件之前,底层数据源不会改变。
在CellValidating 事件的开头放置一个断点。然后运行代码,对网格中的一个单元格进行更改,然后尝试离开该单元格。当断点命中时,查看底层数据源。它不会显示网格单元格中的更改。
由于您没有显示代码,我只能假设在CellValidating 事件中,有“某种”检查来验证单元格中的数据是否无效。您如何检查这是未知的,我们只能假设您检查的是正确的值。
但是,无论如何,如果您检查单元格中的值并确定它是无效值,并希望在编辑“之前”将单元格值设置为其原始值,则调用网格CancelEdit() 方法应该为你做这个。像……
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
if (e.FormattedValue.ToString() == "some invalid value") {
dataGridView1.CancelEdit();
}
}
编辑…
为了提供帮助,我能做的最好的事情就是证明你所说的正在发生……不能用给定的信息重现。
据我所知……
-
网格使用BindingList<T> 作为网格的DataSource。
-
不知道“T”是什么,我们只能猜测它是一个基本类。
-
网格已订阅(连接)其CellValidating 事件。
现在,如果我们尝试重现此...“基本”类可能如下所示,其中该类的一个 int 属性根据您的评论命名为“ItemCode”。此外,还添加了一个名为“ItemName”的附加 string 属性。尽可能基本......
public class ItemClass {
public int ItemCode { get; set; }
public string ItemName { get; set; }
}
为了提供帮助,我们将创建一个 GetData 方法,该方法返回一个包含 15 个 ItemClass 对象的 BindingList<ItemClass>。我们将使用这个绑定列表作为网格的数据源。
private BindingList<ItemClass> GetData() {
BindingList<ItemClass> bl = new BindingList<ItemClass>();
for (int i = 1; i < 16; i++) {
bl.Add(new ItemClass { ItemCode = i, ItemName = "Item " + i });
}
return bl;
}
接下来,我们需要连接网格CellValidating 事件。在此示例中,由于ItemCode 是int 值,CellValidating 事件将是检查并确保用户在单元格中键入有效int 值的好地方。否则,用户可能会键入字符并抛出网格DataError. 在此示例中,如果文本不是有效的int 值,则单元格的值将返回到编辑前的原始值。
这给了我们一个很好的理由来连接这个事件,但它也很方便,所以当用户“更改”单元格值时,我们可以检查BindingList<ItemClass> 列表中的值。
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
if (e.ColumnIndex == 0) {
if (!int.TryParse(e.FormattedValue.ToString(), out int value)) {
dataGridView1.CancelEdit();
}
}
}
因此,创建一个新的 winforms 项目并将 DataGridView 拖放到表单上。除了上面的代码,我们唯一需要的代码如下……
BindingList<ItemClass> GridBindingList;
public Form2() {
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e) {
GridBindingList = GetData();
dataGridView1.DataSource = GridBindingList;
}
我们创建了一个“全局”变量GridBindingList,这样我们就可以在我们设置的任何断点检查它的值。在表单Load 事件中,GridBindingList 填充了测试数据,最后将网格DataSource 设置为此绑定列表。
这是我能破译的最接近你的代码,因为你拒绝显示它。
您声明当用户在网格中的单元格中键入文本然后尝试离开该单元格时……GridBindingList 将使用网格单元格中的文本“在”调用网格CellValidating 事件之前进行更新.
我坚持我的评论,您对此有误。使用上面的代码,你应该可以自己测试一下。
当执行时,上面的代码应该会产生类似于左边表格的东西……
编辑网格中的第二个项目后,它可能看起来像右边的表格......
然后离开单元格,网格CellValidating 事件触发。遇到断点并在事件的第一行停止执行,如下所示。
如图所示,GridBindingList 的第二项还没有像您所说的那样发生变化。此外,在观察列表下方,我们可以看到格式化值“fsdgfdgdf”仍然显示在网格中。
您能否提供重现您所描述内容的代码?从你的评论到这个答案……
“我在底层对象的属性中设置了断点,它在 CellValidating 事件之前 100% 触发。” ...
然后“显示”一个例子。我希望这个例子能证明底层数据源在网格CellValidating 事件触发之前不会改变。