在vb.net中,如何在填充数据后强制在(winform)datarepeater中验证控件?

时间:2011-03-18 20:20:15

标签: vb.net winforms

我有一个带有datarepeater的表单,其中包含通过绑定源填充的各种控件(即datetimepickers,文本框,组合框)。我还在表单上有其他控件,这些控件不属于数据中继器。

我想在填充数据后强制验证所有控件。我已成功强制在我的加载事件结束时使用Me.ValidateChildren()验证非datarepeater控件。但是,它不会触发数据中继器中控件的验证事件。

我尝试了多次尝试在datarepeater控件中设置和移动焦点以尝试启动验证事件的尝试失败。我不确定哪里是最好的地方(例如在ItemCloned中的drawItem?中)来放置代码以及它应该是什么。这是我最近的尝试:

Private Sub DataRepeater1_DrawItem(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs) _
        Handles DataRepeater1.DrawItem

        For i = 0 To e.DataRepeaterItem.Controls.Count - 1
            e.DataRepeaterItem.Controls.Item(i).Focus()
            e.DataRepeaterItem.Controls.Item(0).Focus()
        Next

注意:我成功处理了由用户输入错误导致的数据中继器中的验证事件。但是,我有一个不寻常的情况,即进入我的表单的数据已经对某些控件不好。表单的目的是验证进入它和用户输入的数据。

提前感谢您的帮助。我是vb.net的新手。

3 个答案:

答案 0 :(得分:4)

您是否尝试过调用

DataRepeater1.ValidateChildren()
在调用表单Me.ValidateChildren()

之后

MSDN link

编辑:

你能试试吗

Private Shared Function ValidateAllChildern(cc As ContainerControl) As Boolean
    Return cc.ValidateChildren() And cc.Controls.OfType(Of ContainerControl)().[Select](Function(c) ValidateAllChildern(c)).Aggregate(True, Function(x, y) x And y)
End Function

并致电

ValidateAllChildren(Me)

答案 1 :(得分:1)

以下是我最终使用的内容,效果很好。基本上,您可以在cellformatting和cellvalidating中调用相同的验证函数。单元格格式化处理初始加载时的验证。单元验证处理用户更改的验证。此外,如果您想要对用户输入进行全局更改(例如,更改为大写),请使用EditControlShowing。

一个不错的功能是它显示错误发生在单元格中的小错误图标。以下是细节,fyi。

'handles dgv validation on initial load
Private Sub dgvExample_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
    Handles dgvExample.CellFormatting

    Dim results As String = ""

    If e.RowIndex <> -1 Then
    Select Case e.ColumnIndex
        Case 1, 2 'starting and ending service dates
        results = ValidateDate(e.Value)
        If results = "" Then
            results = ValidateDateRange(e.RowIndex)
        End If
        Case 11 'billed amount
        results = ValidateBilledAmount(e.RowIndex)
    End Select

    dgvExample.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = results
    End If
End Sub


'handles dgv validation from user changes
Private Sub dgvExample_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) _
    Handles dgvExample.CellValidating

    Dim results As String = String.Empty
    dgvExample.CurrentCell.ErrorText = String.Empty

    Select Case dgvExample.Columns(e.ColumnIndex).HeaderText
    Case "Start Date", "End Date"
        results = ValidateDate(e.FormattedValue)
        If results = "" Then
        results = ValidateDateRange(e.RowIndex)
        End If
    Case "Billed Amt"
        dgvExample(e.ColumnIndex, e.RowIndex).Value = FormatNumber(CType(e.FormattedValue, Double), 2, TriState.False, TriState.False, TriState.False).ToString
        results = ValidateBilledAmount(e.RowIndex)
    End Select

    dgvExample.CurrentCell.ErrorText = results

End Sub


'handles dgv dataentry events
    Private Sub dgvExample_EditingControlShowing(ByVal sender As Object, _
                        ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
    Handles dgvExample.EditingControlShowing

    'Change Case to upper case for all textboxes
    Dim editingControl As TextBox = TryCast(e.Control, TextBox)
    If editingControl IsNot Nothing Then
    editingControl.CharacterCasing = CharacterCasing.Upper

    End If
    End Sub

'FUNCTIONS called in above

'check dates not old or in future
Private Function ValidateDate(ByVal dte As String) As String

Dim errorMessage As String = ""

If CType(dte, Date) > Now Then
    errorMessage = "DATE cannot be in the future"
    Return errorMessage
End If

If CType(dte, Date) <= Now.Date.AddYears(-1) Then
    errorMessage = "WARNING: DATE cannot be older than 1 year"
    Return errorMessage
End If

Return errorMessage

End Function


'Checks that start date is less than end date
Private Function ValidateDateRange(ByVal rowIndex As Integer) As String

Dim errorMessage As String = ""

If CType(dgvExample.Rows(rowIndex).Cells(1).Value, Date) > _
   CType(dgvExample.Rows(rowIndex).Cells(2).Value, Date) Then
    errorMessage = "START DATE cannot be after END DATE"
End If

Return errorMessage

End Function


'validates billed amount is currency and in range
Private Function ValidateBilledAmount(ByVal rowIndex As Integer) As String

    Dim errorMessage As String = ""
    Dim billedAmt = dgvExample.Rows(rowIndex).Cells(11).Value 

    If Not String.IsNullOrEmpty(billedAmt) Then
    If IsNumeric(billedAmt) Then
        If CType(billedAmt, Decimal) > 0 Then
        If billedAmt > 100000.0 Then
            errorMessage = "BILLED AMOUNT must not exceed $100,000"
        End If
        Else
        errorMessage = "BILLED AMOUNT must be greater than $0"
        End If
    Else
        errorMessage = "BILLED AMOUNT must be numeric"
    End If
    End If

    If errorMessage = "" Then
    CalculateNewTotal()
    End If

    Return errorMessage
End Function

答案 2 :(得分:0)

我刚试过这个,为了让ValidateChildren工作,你需要使用AddHandler以编程方式设置事件处理程序。

Private Sub DataRepeater1_DrawItem(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs) _         Handles DataRepeater1.DrawItem          
    AddHandler e.DataRepeaterItem.Controls.Item("ctlDateTimePicker").Validated, AddressOf dtpStartingServiceDate_Validating ' Validating DatePicker
    AddHandler e.DataRepeaterItem.Controls.Item("ctlComboBox").Validated, AddressOf cboUnitType_Validating
End Sub

初始化Validated事件处理程序后,可以调用'Me.ValidateChildren()'以使验证运行。我不知道你的情况是好还是坏,但只要控件的值发生变化,验证事件就会执行。

如果有效,请告诉我。