2016-03-23 2 views
0

Ich bin neu in WPF. Der Datenkontext des Formulars enthält ein StartTime- und ein EndTime-Feld (mit MVVM), das ich erfolgreich an eigene Textfelder gebunden habe. Ich versuche, eine Überprüfung zu erstellen, um zu überprüfen, ob ein neuer benutzerdefinierter Wert StartTime vor dem EndTime Wert ist. Der folgende Code scheint das Feld EndTime nicht an den Validierungsparameter Maximum zu binden.Bindung an eine ValidationRule in WPF

XAML:

<TextBox> 
    <TextBox.Text> 
     <Binding Path="StartTime" UpdateSourceTrigger="LostFocus" StringFormat="{}{0:hh}:{0:mm}"> 
      <Binding.ValidationRules>            
       <local:ValidateTime> 
        <local:ValidateTime.Maximum> 
         <local:ValidationParameter Parameter="{Binding EndTime, StringFormat=hh\\:mm}" /> 
        </local:ValidateTime.Maximum> 
       </local:ValidateTime> 
      </Binding.ValidationRules> 
     </Binding> 
    </TextBox.Text> 
</TextBox> 

anzeigen Modell:

public class ValidationParameter : DependencyObject 
{ 
    public static readonly DependencyProperty ParameterProperty = DependencyProperty.Register(
     "Parameter", 
     typeof(string), 
     typeof(ValidationParameter), 
     new FrameworkPropertyMetadata(null)); 

    public string Parameter 
    { 
     get { return (string)GetValue(ParameterProperty); } 
     set { SetValue(ParameterProperty, value); } 
    } 
} 

public class ValidateTime : ValidationRule 
{ 
    private TimeSpan _Minimum = new TimeSpan(0, 0, 0); 
    private TimeSpan _Maximum = new TimeSpan(23, 59, 9); 
    private ValidationParameter _MinimumProperty; 
    private ValidationParameter _MaximumProperty; 

    public ValidationParameter Minimum 
    { 
     get 
     { 
      return _MinimumProperty; 
     } 
     set 
     { 
      TimeSpan ts; 
      if (TimeSpan.TryParse(value.Parameter, out ts)) 
      { 
       _Minimum = ts; 
       _MinimumProperty = value; 
      } 
     } 
    } 

    public ValidationParameter Maximum 
    { 
     get 
     { 
      return _MaximumProperty; 
     } 
     set 
     { 
      TimeSpan ts; 
      if (TimeSpan.TryParse(value.Parameter, out ts)) 
      { 
       _Maximum = ts; 
       _MaximumProperty = value; 
      } 
     } 
    } 

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) 
    { 
     string formattedValue = value.ToString(); 
     if (Regex.IsMatch(formattedValue, @"^\d{4}$")) 
     { 
      formattedValue = string.Format("{0}:{1}", formattedValue.Substring(0, 2), formattedValue.Substring(2, 2)); 
     } 
     TimeSpan convertedValue; 
     if (TimeSpan.TryParseExact(formattedValue, "g", System.Globalization.CultureInfo.CurrentCulture, out convertedValue)) 
     { 
      if (convertedValue > _Maximum) 
      { 
       return new ValidationResult(false, string.Format("Time must be before {0}.", _Maximum.ToString("g"))); 
      } 
      else if (convertedValue < _Minimum) 
      { 
       return new ValidationResult(false, string.Format("Time must be after {0}.", _Minimum.ToString("g"))); 
      } 
      return ValidationResult.ValidResult; 
     } 
     else 
     { 
      return new ValidationResult(false, string.Format("'{0}' is not a valid time entry.", value.ToString())); 
     } 
    } 
} 

Der Code funktioniert, wenn ich die Parameter auf einen statischen Wert wie der folgende Satz, aber ich brauche diese Validierung dynamisch:

<local:ValidateTime.Maximum> 
    <local:ValidationParameter Parameter="12:00" /> 
</local:ValidateTime.Maximum> 
+0

Duplikat http://stackoverflow.com/questions/36083103/binding-inputvalidation- Zusätzliche Daten verwenden-dependencyproperty/36087560 # 36087560 –

Antwort

0

Zuerst möchten Sie Ihrer TextBox einen Namen wie folgt geben:

<TextBox Name="StartTime"/> 

Dann stellen Sie die Parameter für die Validierung wie folgt:

<local:ValidateTime.Maximum> 
    <local:ValidationParameter Parameter="{Binding ElementName=StartTime, Path=Text" /> 
</local:ValidateTime.Maximum> 

Wenn die Validierung funktioniert wie Sie sagten, Sie alle eingestellt werden sollte.

Sie können mit Ihrem EndTime TextBox das gleiche tun, wenn Sie auch wollen, vorausgesetzt, Sie eine Arbeits Regel schreiben für sie

0

Sie wahrscheinlich die Tatsache work around müssen, dass ValidationRules sind nicht in der visuellen oder logische Bäume, die führt dazu, dass Bindungen an DataContext, ElementName und RelativeSource fehlschlagen.

0

In meinem Fall

<local:RangeValidation ValidationStep="UpdatedValue"/> 

geholfen. So übergeben Sie das DependencyObject als Wert (.dataitem) einschließlich Ihres Datacontext und müssen keinen Parameter an die Validierung übergeben. BR, Daniel

Credits BTW nicht auf mee, fand es einfach, aber nicht mehr, wer den Hinweis gab :)