I am new to WPF. The form's data context includes a StartTime
and an EndTime
field (using MVVM), which I have successfully bound to their own text boxes. I am trying to create a validation to check that a new user-entered StartTime
is before the EndTime
value. The following code does not seem to bind the EndTime
field to the validation parameter Maximum
.
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>
View model:
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()));
}
}
}
The code works if I set the parameter to a static value like the following, but I need this validation to be dynamic:
<local:ValidateTime.Maximum>
<local:ValidationParameter Parameter="12:00" />
</local:ValidateTime.Maximum>