質問者
Validatingイベントでキャンセルしてもデータセットに更新される

質問
-
DataSourceUpdateModeがOnValidationの状態で、TextBoxのValidatingイベントでキャンセルしたのですが、値が更新されてしまいました。
以下が行ったことです。
・新規WindowsApplication1を作成
・DataSet1を作成
・Column1(Int32)を持つDataTable1を作成
・Form1にデータソースウィンドウから「詳細」でDataTable1をドラッグ&ドロップする
・Form1にツールバーからTextBoxをドラッグ&ドロップする(Column1TextBoxのValidationを起こすため)
・Form1にツールバーからButton1をドラッグ&ドロップする
・Form1.vbに以下のコードを貼り付け (処理概要:3文字以上の入力をはじく)Code SnippetPublic Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Button1.CausesValidation = False
End SubPrivate Sub Column1TextBox_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Column1TextBox.Validating
Dim tb As TextBox = CType(sender, TextBox)
If tb.Text <> "" Then
If Len(tb.Text) > 2 Then
MsgBox("形式エラー")
e.Cancel = True
End If
End If
End SubPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MsgBox("Column1:'" & CType(Me.DataTable1BindingSource.Current, DataRowView).Row("Column1").ToString & "'")
End SubEnd Class
・実行
①レコード追加(+)ボタンを押す→テキストボックスに「aaa」と入力し、TABキーを押す→「形式エラー」と出る→Button1を押す→「Column1:''」と出る・一旦終了し、再度実行
②レコード追加(+)ボタンを押す→テキストボックスに「111」と入力し、TABキーを押す→「形式エラー」と出る→Button1を押す→「Column1:'111'」と出る
「111」と入力し形式エラーとなった場合、Button1を押すと「Column1:''」となることを希望していました。コードのどこかが悪さをしているのでしょうか?ちなみに
・DataSourceUpdateModeはデフォルトのOnValidationになっています。
・ComboBoxに変えてみても同様でした。また、
舞台裏で: .NET Framework 2.0 における Windows フォーム データ バインドの改良点 (第 1 部)
http://www.microsoft.com/japan/msdn/net/winforms/wfbindp1.aspx
の
DataSourceUpdateMode を使用する
を読むと、
「…、値が検証に合格すると更新されます。」
と書いてありました。
この「検証」の意味を私は「TextBox.Validating内で e.Cancel = True とされたかどうか」を含む、と捉えていました。
従って、「111」と入力してValidationでキャンセル(e.Cancel = True)されると更新されないと思っていました。とりあえずこの影響が出ないようにプログラムの作り方を変えたのですが、気になっておりまして、ご教示頂ければ幸いです。
環境:
Microsoft Visual Studio 2005 Version 8.0.50727.42 (RTM.050727-4200)
Microsoft .NET Framework Version 2.0.50727インストールされている Edition: VB Express
Windows Vista Business
すべての返信
-
1つリンクと引用を忘れていたので補足します。
DataSourceUpdateMode 列挙体
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.datasourceupdatemode(VS.80).aspxOnValidation
コントロール プロパティが検証されると、データ ソースが更新されます。
検証後、コントロール プロパティの値の書式も再設定されます。 -
自己レスばかりですみません。
投稿する前にもちっと考えるべきだったと激しく後悔orz。でもわかったことがあるのでスレを更新しておきます。
さて、Column1をInt32からStringに変更してみると、①でもColumn1:'aaa'と表示されました。
従って、やはりColumn1TextBox.Validatingでのe.Cancelは
「…、値が検証に合格すると更新されます。」
で言う「検証」とは無関係だと思いました。ではいったいこの「検証」とは何のこと?と思い、とりあえずこの「検証」を失敗させる方法を見つけることで解明しようと考えました。
そこで今度はDataSet側の検証に関係ありそうな情報を探し、
方法 : 列の変更時にデータを検証する
http://msdn2.microsoft.com/ja-jp/library/0f7ey06d(VS.80).aspxに
「・列変更イベント ハンドラで列エラー (SetColumnError) を設定して、指定された値を拒否します。」
とあるのを見つけました。ここのサンプルコードにある
DataRow.SetColumnError メソッド (DataColumn, String)
http://msdn2.microsoft.com/ja-jp/library/system.data.datarow.setcolumnerror(VS.80).aspxにエラー文字列をセットすれば検証が失敗しデータセットへの更新はなされなくなるかな、と期待したのですが、何のメッセージも出ず値はデータセットに更新されました。以下がそのコードです。
Code SnippetPartial Class DataSet1
Partial Class DataTable1DataTable
Private Sub DataTable1DataTable_ColumnChanging(ByVal sender As System.Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanging
If (e.Column.ColumnName = Me.Column1Column.ColumnName) Then
'ユーザー コードをここに追加してください
If Len(CStr(e.ProposedValue)) > 2 Then
e.Row.SetColumnError(e.Column, "形式エラー")
Console.WriteLine("ここ通った。")
Else
e.Row.SetColumnError(e.Column, "")
End If
End If
End Sub
End Class
End Class検証って一体何を指しているのでしょう?