With WPF, you have access to the visual tree and with this in hand, I created my little validator called 'BadAssValidation' :) which enumerates down the tree to find controls to validate.
What I do is that on the submit button in my application, I use the 'Command Parameter' and I pass in the Grid where all the controls that I want to validate exists.
<Button Height="23" HorizontalAlignment="Right" Margin="0,0,6,26" Name="btSave" VerticalAlignment="Bottom" Width="75"
Command="{Binding Path=SaveOrderCommand}" CommandParameter="{Binding ElementName=OrderGrid}" Content="Save" />
Note that each individual control needs to have been bound to their own validator in order for the BadAssValidation to check if they have erroros.
<Binding.ValidationRules>
<validate:valMXvarchar300/>
</Binding.ValidationRules>
In the View Model, I now run the BadAssValidation on the Grid. The validator will enumerate through the visual tree to find matching controls. It will then check if any of these controls have failed validation.
'Validate with BadAssValidationDim validationObj As New Validator.BadAssValidation
If Not validationObj.enumVisual(param) Then
...
And here is the BadAssValidator class:
Public Class BadAssValidation
Private hasErrors As Boolean = False
''' <summary>
''' <para>Validation for all textboxes and comboboxes on UserControl.
''' </para>
''' <para>This method loops through textboxes and comboboxes on usercontrol
''' and calls their Binding validation rule if one exists.</para>
''' </summary>
''' <param name="visual">Visual</param>
''' <returns>Boolean: True if all controls pass validation : else false.</returns>
''' <remarks></remarks>
Public Function enumVisual(ByVal visual As Visual) As Boolean
Try
''Count children in visual tree node
Dim j As Integer = VisualTreeHelper.GetChildrenCount(visual) - 1
''Loop through visual child
For i As Integer = 0 To j
Dim childvisual As Visual = CType(VisualTreeHelper.GetChild(visual, i), Visual)
''Check if child has a name
If Not childvisual.DependencyObjectType.Name Is Nothing OrElse Not childvisual.DependencyObjectType.Name = "" Then
''Check if child is of 'TextBox'
If childvisual.DependencyObjectType.Name = "TextBox" Then
Dim txtbox As TextBox = childvisual
''Update source of control
If Not txtbox.GetBindingExpression(TextBox.TextProperty) Is Nothing Then txtbox.GetBindingExpression(TextBox.TextProperty).UpdateSource()
''Check if control has errors
If System.Windows.Controls.Validation.GetHasError(txtbox) Then hasErrors = True
'for testing, need to create a new object before use ': st.Append(txtbox.Name & vbNewLine) : MessageBox.Show(st.ToString)
End If
''Check if child is of 'ComboBox'
If childvisual.DependencyObjectType.Name = "ComboBox" Then
Dim combox As ComboBox = childvisual
''Update source of control --Tag
If Not combox.GetBindingExpression(ComboBox.TagProperty) Is Nothing Then combox.GetBindingExpression(ComboBox.TagProperty).UpdateSource()
''Update source of control --SelectedValue
If Not combox.GetBindingExpression(ComboBox.SelectedValueProperty) Is Nothing Then combox.GetBindingExpression(ComboBox.SelectedValueProperty).UpdateSource()
''Check if control has errors
If System.Windows.Controls.Validation.GetHasError(combox) Then hasErrors = True
'for testing, need to create a new object before use ': st.Append(combox.Name & vbNewLine) : MessageBox.Show(st.ToString)
End If
''Check if child is of 'DatePicker'
If childvisual.DependencyObjectType.Name = "DatePicker" Then
Dim dPicker As DatePicker = childvisual
''Update source of control
If Not dPicker.GetBindingExpression(DatePicker.SelectedDateProperty) Is Nothing Then dPicker.GetBindingExpression(DatePicker.SelectedDateProperty).UpdateSource()
''Check if control has errors
If System.Windows.Controls.Validation.GetHasError(dPicker) Then hasErrors = True
'for testing, need to create a new object before use ': st.Append(txtbox.Name & vbNewLine) : MessageBox.Show(st.ToString)
End If
End If
enumVisual(childvisual)
Next i
Catch ex As Exception
Dim resultObj As New Results
resultObj.displayResult(ex)
End Try
Return hasErrors
End Function
'Private st As System.Text.StringBuilder
End Class
Public Class val0ApprovedRegions
Inherits ValidationRule
Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As System.Globalization.CultureInfo) As System.Windows.Controls.ValidationResult
Dim valChar As Char = CChar(value)
If valChar = "T" Then
Return New ValidationResult(False, "Approved regions must be selected.")
Else
Return New ValidationResult(True, Nothing)
End If
End Function
End Class
No comments:
Post a Comment