2
private void Cource_Load(object sender, EventArgs e)
{
    //fill dataset by using .GetAllCourses() function 
    DataSet ds = new DataAccess.newCourcesDAC().GetAllCourses();

    //define and set BindingSource to tblCourses of dataset
    BindingSource BS = new BindingSource();
    BS.DataSource = ds;
    BS.DataMember = "tblCourses";

    //bind datagridview to Bindingsource
    ds.Tables["tblCourses"].RowChanging += new  DataRowChangeEventHandler(Cource_RowChanging);
    dataGridView1.DataSource = BS;

    //bind for texbox to navigat 4 column of Cource table
    txtCourseID.DataBindings.Add("Text", BS, "CourseID");
    txtCourseName.DataBindings.Add("Text", BS, "CourseName");
    txtPrequest.DataBindings.Add("Text", BS, "Prequest");
    txtCourseContent.DataBindings.Add("Text", BS, "CourseContent");
}
**void Cource_RowChanging(object sender, DataRowChangeEventArgs e)
    {
        if ( e.Action==DataRowAction.Add)
        {
            if (((int)e.Row["CourseID", DataRowVersion.Proposed]) < 10)
            {
                e.Row.SetColumnError("CourseID", "cource id must < 10");
                e.Row.CancelEdit();
            }
        }
    }**

我有一个数据集(ds)和一个表(tblCourse),它有4列,使用绑定源绑定到4个文本框。我想通过 RowChanging 事件向数据表添加新记录时验证数据。

当发生指定条件时,我想用 [ e.Row.CancelEdit();] 取消行。

但我收到此错误:无法在 OnRowChanging 事件中调用 CancelEdit()。抛出异常以取消此更新。

4

2 回答 2

1

为了任何可能偶然发现这个旧线程的人的利益,我将发布一个解决方案来解决与此问题相关的一些“陷阱”。

  1. 尽管错误消息说什么,在 RowChanging 中与 Try-Catch 一起引发异常不会删除新行。我不能说当抛出错误时它永远不会删除该行,只是我还没有看到它发生。

  2. 在没有 Try-Catch 的情况下抛出异常会将行标记为有错误。如果您有任何 WPF 数据网格代码来指示验证错误 - 例如显示我喜欢的红色复选标记 - 那么错误将正确显示。该行不会被删除。

  3. 在我迄今为止看到的任何情况下,在 RowChanging 中调用 e.Delete 也不会删除该行。如果设置断点并检查 RowState,它将设置为 Detached。下次触发 RowChanged 事件时,RowState 将恢复为 e.Added。即使可以在某些其他条件下删除 RowChanging 中的一行,这也可能不会将数据集或后端数据库中的任何标识列重置为添加之前的最后一个值。

  4. 下面我相当简单的 VB.Net 解决方法使用标志变量(我通常将我的变量放在数据类级别)来识别 RowChanging 中是否发生取消,然后在 RowChanged 中采取适当的操作并重置标志。到目前为止,我还没有遇到任何问题,除了一些“该行已从表中删除并且没有任何数据。BeginEdit() 将允许在该行中创建新数据。” 当遇到删除的行时,我的代码中的其他地方出现异常,通过对 RowState 设置为 Detached 的一些简单检查来修复这些异常。我希望这有帮助。

    私有 LastRowAdditionCanceled 作为布尔值

    Public Sub RowChanging(ByVal sender As Object, ByVal e As DataRowChangeEventArgs)
    
         If e.Action = DataRowAction.Add Then
        'Add the conditions where you want to cancel the row addition above
        LastRowAdditionCanceled = True
          End If
    End Sub
    
    
    
    Public Sub RowChanged(ByVal sender As Object, ByVal e As DataRowChangeEventArgs)
    
          If LastRowAdditionCanceled = False Then
             'execute your usual RowChanged code here
    
          Else
                e.Row.RejectChanges()
                LastRowAdditionCanceled = False
          End If
    End Sub
    
于 2016-06-13T18:24:04.210 回答
0

使用事件“RowChanged”,如果要删除该行,可以调用 e.Row.Delete()。我附上了示例代码,您可以在其中看到如果插入的值为“2”,则删除该行:

 class Program
{
    static void Main(string[] args)
    {
        DataTable dataTable = new DataTable();
        dataTable.Columns.Add("ID", typeof(int));
        dataTable.RowChanged += new DataRowChangeEventHandler(dt_RowChanged);

        dataTable.Rows.Add(1);
        dataTable.Rows.Add(2);
        dataTable.Rows.Add(3);

        Console.WriteLine("Total rows: {0}", dataTable.Rows.Count);
        foreach (DataRow item in dataTable.Rows)
        {
            Console.WriteLine(item["ID"]);
        }

        Console.Read();
    }

    private static void dt_RowChanged(object sender, DataRowChangeEventArgs e)
    {
        if (e.Action == DataRowAction.Add)
        {
            if (((int)e.Row["ID"]) == 2)
            {
                e.Row.Delete();
            }
        }
    }
}
于 2012-07-18T07:54:22.370 回答