2012-07-18 119 views
0

我想驗證一些控件,但前提是選中了我的複選框。 (在這個例子中我只顯示一個文本框來驗證)如果勾選複選框,啓用驗證規則

我試着用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

我就是這麼做的:

資源定義樣式:

<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> 

依賴性Pr operty:

#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 

LqvDatabaseServerLqvDatabaseServerValidationErrors都在我的ViewModel屬性。