我是WPF的新手。表单的数据上下文包括StartTime
和EndTime
字段(使用MVVM),我已成功绑定到自己的文本框。我正在尝试创建验证,以检查新用户输入的StartTime
是否在EndTime
值之前。以下代码似乎不会将EndTime
字段绑定到验证参数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>
查看型号:
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()));
}
}
}
如果我将参数设置为如下所示的静态值,则代码可以工作,但我需要将此验证设置为动态:
<local:ValidateTime.Maximum>
<local:ValidationParameter Parameter="12:00" />
</local:ValidateTime.Maximum>
答案 0 :(得分:0)
首先,您要为TextBox命名,如下所示:
<TextBox Name="StartTime"/>
然后设置验证参数,如下所示:
<local:ValidateTime.Maximum>
<local:ValidationParameter Parameter="{Binding ElementName=StartTime, Path=Text" />
</local:ValidateTime.Maximum>
如果验证工作就像你说的那样你应该全部设定。
如果您想要为其编写工作规则,您可以使用EndTime TextBox执行相同的操作
答案 1 :(得分:0)
您可能需要work around ValidationRules
不在视觉或逻辑树中的事实,这会导致绑定到DataContext
,ElementName
和RelativeSource
失败。
答案 2 :(得分:0)
就我而言
<local:RangeValidation ValidationStep="UpdatedValue"/>
帮助。因此,您将DependencyObject作为值(.dataitem)传递,包括您的Datacontext,并且无需将参数传递给Validation。 BR, 丹尼尔
顺便说一下BTW不是为了我,只是找到它但不记得是谁给了提示:)