これを使っているシステムの開発に、あんまりお世話になったことがない気がします。
やはり入力エラーなんかはメッセージ表示のほうが好まれるのかな。
以前やった、ErrorProvider でエラー表示しつつ、メッセージも表示というやつを実装してみました。
あと、AutoValidate の値毎にどんな感じで動作するかを確かめる為に、
ErrorProviderTestUC というユーザーコントロールを作って実装してみました。
AutoValidate は ContainerControl が持ってるので、当然その 派生クラス でないと使えません。
Panel とかは ContainerControl のもう一階層上の ScrollableControl を継承してるんですね。(なので当然 AutoValidate はない)
GroupBox は ScrollableControl のさらに上の Control を継承してました。(なので当然 AutoValidate はない)
興味深いですね~。
■参考文献
ErrorProvider クラス
ContainerControl クラス
ScrollableControl クラス
Panel クラス
GroupBox クラス
■実行画像
全体像
一番上のユーザーコントロールのエラーメッセージ
■ユーザーコントロールのコード
Public Class ErrorProviderTestUC
Private m_errorProvider As ErrorProvider
< System.ComponentModel.Description("Validating イベントで エラーとなった時に表示するための ErrorProvider を指定します")> _
Public Property ErrorProvider() As ErrorProvider
Get
If Not Me.DesignMode AndAlso Me.m_errorProvider Is Nothing Then
Throw New InvalidOperationException("ErrorProvider が Nothing です")
End If
Return Me.m_errorProvider
End Get
Set(ByVal value As ErrorProvider)
Me.m_errorProvider = value
End Set
End Property
Private Sub TextBox1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
If Not New ArrayList(New String() {"ふじこ", "えでん"}).Contains(Me.TextBox1.Text) Then
Me.ErrorProvider.SetError(Me.TextBox1, "うちに居る犬の名前を入力してください")
e.Cancel = True
End If
End Sub
Private Sub TextBox2_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox2.Validating
If Me.TextBox1.Text = "ふじこ" Then
If 3.ToString() <> Me.TextBox2.Text Then
Me.ErrorProvider.SetError(Me.TextBox2, "年齢が違います")
Me.ErrorProvider.SetIconAlignment(Me.TextBox2, ErrorIconAlignment.BottomLeft)
e.Cancel = True
End If
Else
If 2.ToString() <> Me.TextBox2.Text Then
Me.ErrorProvider.SetError(Me.TextBox2, "トシがちがうトシが")
Me.ErrorProvider.SetIconAlignment(Me.TextBox2, ErrorIconAlignment.TopLeft)
Me.ErrorProvider.SetIconPadding(Me.TextBox2, 10)
e.Cancel = True
End If
End If
End Sub
Protected Overrides Sub OnAutoValidateChanged(ByVal e As System.EventArgs)
MyBase.OnAutoValidateChanged(e)
' AutoValidate を Label に表示する
Me.Label1.Text = Me.AutoValidate.ToString()
End Sub
End Class
■Form のコード
Public Class ErrorProviderTest
Private m_testDataTable As DataTable
Private Sub ErrorProviderTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.AutoValidate = Windows.Forms.AutoValidate.Disable
' SetError されたら、ずっと点滅
Me.ErrorProvider1.BlinkStyle = ErrorBlinkStyle.AlwaysBlink
' 現在 SetError されているものと違うものが SetError されたらしばし点滅
Me.ErrorProvider2.BlinkStyle = ErrorBlinkStyle.BlinkIfDifferentError
Me.ErrorProvider2.BlinkRate = 300 ' 点滅の間隔
' Validation を行わない
Me.ErrorProviderTestUC1.AutoValidate = Windows.Forms.AutoValidate.Disable
Me.ErrorProviderTestUC1.ErrorProvider = Me.ErrorProvider1
Me.ErrorProviderTestUC1.BackColor = Color.PeachPuff
' コントロールのフォーカスが移動した時に Validation を行う
' (ただし、次のコントロールや前のコントロールに移動できる)
Me.ErrorProviderTestUC2.AutoValidate = Windows.Forms.AutoValidate.EnableAllowFocusChange
Me.ErrorProviderTestUC2.ErrorProvider = Me.ErrorProvider2
Me.ErrorProviderTestUC2.BackColor = Color.PaleGreen
' コントロールのフォーカスが移動した時に Validation を行う
' (ただし、次のコントロールや前のコントロールに移動できない)
Me.ErrorProviderTestUC3.AutoValidate = Windows.Forms.AutoValidate.EnablePreventFocusChange
Me.ErrorProviderTestUC3.ErrorProvider = Me.ErrorProvider2
Me.ErrorProviderTestUC3.BackColor = Color.LightSkyBlue
' 監視する対象を DataTable にする
Me.m_testDataTable = New DataTable("Dogs")
Me.m_testDataTable.Columns.Add("DOG_NAME", GetType(String))
Me.m_testDataTable.Columns.Add("DOG_AGE", GetType(Integer))
Dim ds As DataSet = New DataSet("DogsTestDataSet")
ds.Tables.Add(Me.m_testDataTable)
Me.ErrorProvider3.BindToDataAndErrors(ds, Me.m_testDataTable.TableName)
Me.m_testDataTable.Rows.Add("ふじこ", 3)
Me.m_testDataTable.Rows.Add("えでん", 2)
Me.ErrorProvider3.UpdateBinding()
Me.DataGridView1.DataSource = Me.m_testDataTable
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' AutoValidate が Disable の UserConrol の中身の Validation を行う
Me.ErrorProviderTestUC1.ValidateChildren()
' エラーメッセージを表示する
Dim buffer As System.IO.StringWriter = New System.IO.StringWriter
For Each cntrl As Control In Me.ErrorProviderTestUC1.Controls
If Me.ErrorProvider1.GetError(cntrl) <> "" Then
buffer.WriteLine(Me.ErrorProvider1.GetError(cntrl))
End If
Next
If buffer.ToString() <> "" Then
MessageBox.Show(buffer.ToString(), "error", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
For Each row As DataRow In Me.m_testDataTable.Rows
If IsDBNullOrNullOrEmpty(row("DOG_NAME")) OrElse IsDBNullOrNullOrEmpty(row("DOG_AGE")) Then
row.RowError = "入力に誤りがあります。"
If IsDBNullOrNullOrEmpty(row("DOG_NAME")) Then
row.SetColumnError("DOG_NAME", "犬の名前を入力してください")
End If
If IsDBNullOrNullOrEmpty(row("DOG_AGE")) Then
row.SetColumnError("DOG_AGE", "犬の年齢を入力してください")
End If
End If
Next
End Sub
Private Function IsDBNullOrNullOrEmpty(ByVal o As Object) As Boolean
If o Is Nothing Then Return True
If TypeOf (o) Is DBNull Then Return True
Return String.IsNullOrEmpty(Convert.ToString(o))
End Function
End Class