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();
            }
        }
    }**

私は、バインディングソースを使用して4つのテキストボックスにバインドされた4つの列を持つテーブル(tblCourse)を持つデータセット(ds)を持っています。RowChanging イベントでデータテーブルに新しいレコードを追加する際にデータを検証したい。

指定した条件が発生した場合、[e.Row.CancelEdit();]で行をキャンセルしたい。

しかし、私はこのエラーを受け取ります: OnRowChanging イベント内で CancelEdit() を呼び出すことはできません。この更新をキャンセルするには、例外をスローします。

4

2 に答える 2

1

この古いスレッドに出くわす可能性のある人のために、この問題に関連するいくつかの「落とし穴」に対処する解決策を投稿します。

  1. エラー メッセージの内容にかかわらず、Try-Catch と組み合わせて RowChanging で例外をスローしても、新しい行は削除されません。エラーがスローされたときに行が削除されないとは言えませんが、まだ発生していないだけです。

  2. Try-Catch なしで例外をスローすると、行にエラーがあるとマークされます。検証エラーを示す WPF データグリッド コードがある場合 (私が好きな赤いチェック マークを表示するなど)、エラーは正しく表示されます。ただし、行は削除されません。

  3. RowChanging で e.Delete を呼び出しても、これまでに見たどの条件下でも行は削除されません。ブレークポイントを設定して RowState を確認すると、Detached に設定されます。次に RowChanged イベントが発生すると、RowState は e.Added に戻ります。他の条件下で RowChanging の行を削除できたとしても、データセットまたはバックエンド データベースの ID 列が、追加前の最後の値にリセットされることはおそらくありません。

  4. 以下の非常に単純な VB.Net の回避策では、フラグ変数 (私は通常、データ クラス レベルに配置します) を使用して、RowChanging でキャンセルが発生したかどうかを識別し、RowChanged で適切なアクションを実行して、フラグをリセットします。これまでのところ、「この行はテーブルから削除されており、データがありません。BeginEdit() を使用すると、この行に新しいデータを作成できます。」という例外を除いて、これに関する問題は発生していません。削除された行が検出されたときのコードの他の場所での例外は、RowState が Detached に設定されているかどうかのいくつかの簡単なチェックで修正されました。これが役立つことを願っています。

    Private LastRowAdditionCanceled As Boolean

    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 に答える