我想验证一些控件,但只有选中了我的复选框。 (在此示例中,我只显示一个要验证的文本框)
我尝试使用BindingGroup,但这意味着该复选框也经过验证,这会给我错误的结果。
现在我尝试使用MultiBinding:
<CheckBox Name="chkUseLqv"
Grid.Row="6"
Grid.Column="0"
Margin="0,0,8,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="Use LQV"
IsChecked="{Binding LqvConfigurationEnabled}" />
[...]
<GroupBox Grid.Row="1"
Grid.RowSpan="6"
Grid.Column="4"
Margin="5"
Header="LQV Configuration"
IsEnabled="{Binding LqvConfigurationEnabled}">
<Grid>
<TextBox Name="txtLqvDatabaseServer"
Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Center"
Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}">
<TextBox.Text>
<MultiBinding Converter="{Converters:LqvConfigurationMultiBindingConverter}" UpdateSourceTrigger="PropertyChanged">
<MultiBinding.ValidationRules>
<LocalValidationRules:LqvDatabaseServerValidator />
</MultiBinding.ValidationRules>
<Binding ElementName="chkUseLqv" Path="IsChecked" />
<Binding Path="LqvDatabaseServer" />
</MultiBinding>
</TextBox.Text>
</TextBox>
</Grid>
</GroupBox>
我的验证员:
Imports System.Text.RegularExpressions
Namespace ValidationRules
Public Class LqvDatabaseServerValidator
Inherits ValidationRule
Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As System.Globalization.CultureInfo) As System.Windows.Controls.ValidationResult
Dim useLqv = CType(value, Object()).OfType(Of Boolean).First()
Dim valueFromSource = CType(value, Object()).OfType(Of String).FirstOrDefault()
If useLqv Then
If String.IsNullOrEmpty(valueFromSource) Then
Return New ValidationResult(False, "This field is required!")
End If
If Not (
Regex.IsMatch(valueFromSource, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$") OrElse
Regex.IsMatch(valueFromSource, "^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$")
) Then
Return New ValidationResult(False, "Invalid input!")
End If
End If
Return ValidationResult.ValidResult
End Function
End Class
End Namespace
转换器:
Imports System.Windows.Markup
Namespace Converters
Public Class LqvConfigurationMultiBindingConverter
Inherits MarkupExtension
Implements IMultiValueConverter
Public Sub New()
End Sub
Private _orig As Object()
Public Function Convert(ByVal values() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert
_orig = values
Return values.OfType(Of String).FirstOrDefault()
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetTypes() As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
Return _orig
End Function
Public Overrides Function ProvideValue(ByVal serviceProvider As System.IServiceProvider) As Object
Return New LqvConfigurationMultiBindingConverter()
End Function
End Class
End Namespace
但它不起作用。你能救我吗?
答案 0 :(得分:0)
我是这样做的:
在资源中定义样式:
<Style x:Key="lqvDependingFields" TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate />
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=chkUseLqv, Path=IsChecked}" Value="true">
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource ValidationErrorTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
有一个复选框:
<CheckBox Name="chkUseLqv"
Grid.Row="6"
Grid.Column="0"
Margin="0,0,8,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="Use LQV"
IsChecked="{Binding LqvConfigurationEnabled}" />
使用控件上的样式:
<TextBox Name="txtLqvDatabaseServer"
Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Center"
DependencyProperties:AttachedWindowProperties.HasValidationError="{Binding LqvDatabaseServerValidationError}"
Style="{StaticResource lqvDependingFields}">
<TextBox.Text>
<Binding NotifyOnSourceUpdated="True"
Path="LqvDatabaseServer"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<LocalValidationRules:LqvDatabaseServerValidator ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
依赖属性:
#Region "HasValidationErrorProperty"
Public Shared ReadOnly HasValidationErrorProperty As DependencyProperty =
DependencyProperty.RegisterAttached("HasValidationError", GetType(Boolean), GetType(AttachedWindowProperties),
New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
Nothing, AddressOf CoerceHasValidationError))
Public Shared Function GetHasValidationError(ByVal d As DependencyObject) As Boolean
Return CBool(d.GetValue(HasValidationErrorProperty))
End Function
Public Shared Sub SetHasValidationError(ByVal d As DependencyObject, ByVal value As Boolean)
d.SetValue(HasValidationErrorProperty, value)
End Sub
Private Shared Function CoerceHasValidationError(ByVal d As DependencyObject, ByVal baseValue As Object) As Object
Dim result As Boolean = CBool(baseValue)
If BindingOperations.IsDataBound(d, HasValidationErrorProperty) Then
If GetHasErrorDescriptor(d) Is Nothing Then
Dim desc = DependencyPropertyDescriptor.FromProperty(Validation.HasErrorProperty, d.GetType)
desc.AddValueChanged(d, AddressOf OnHasErrorChanged)
SetHasErrorDescriptor(d, desc)
result = Validation.GetHasError(d)
End If
Else
If GetHasErrorDescriptor(d) IsNot Nothing Then
Dim desc As DependencyPropertyDescriptor = GetHasErrorDescriptor(d)
desc.RemoveValueChanged(d, AddressOf OnHasErrorChanged)
SetHasErrorDescriptor(d, Nothing)
End If
End If
Return result
End Function
Private Shared Sub OnHasErrorChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim d As DependencyObject = TryCast(sender, DependencyObject)
If d IsNot Nothing Then
d.SetValue(HasValidationErrorProperty, d.GetValue(Validation.HasErrorProperty))
End If
End Sub
Private Shared ReadOnly HasErrorDescriptorProperty As DependencyProperty =
DependencyProperty.RegisterAttached("HasErrorDescriptor", GetType(DependencyPropertyDescriptor), GetType(AttachedWindowProperties))
Private Shared Function GetHasErrorDescriptor(ByVal d As DependencyObject) As DependencyPropertyDescriptor
Return CType(d.GetValue(HasErrorDescriptorProperty), DependencyPropertyDescriptor)
End Function
Private Shared Sub SetHasErrorDescriptor(ByVal d As DependencyObject, ByVal value As DependencyPropertyDescriptor)
d.SetValue(HasErrorDescriptorProperty, value)
End Sub
#End Region
LqvDatabaseServer
和LqvDatabaseServerValidationErrors
是我的ViewModel中的属性。