要实现验证,您应该将“ValidationStates”组添加到控件的 VisualStateManager。
我将用TestProperty 属性说明简单的自定义控件TestControl。
Generic.xaml 中的样式,根据状态显示蓝色文本或带有第一条错误消息的红色边框:
<Style TargetType="local:TestControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TestControl">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid" />
<VisualState x:Name="InvalidFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InvalidBorder" Storyboard.TargetProperty="Visibility" Duration="0">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="InvalidUnfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InvalidBorder" Storyboard.TargetProperty="Visibility" Duration="0">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock Text="{TemplateBinding TestProperty}" Foreground="Blue" />
<Border x:Name="InvalidBorder" BorderBrush="Red" BorderThickness="2" Visibility="Collapsed">
<TextBlock Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" Foreground="Red" FontWeight="Bold" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
有3种状态:
-
有效 - 没有验证错误。
-
InvalidFocused - 当您将焦点设置到处于无效状态的控件时应用。默认控件在此状态下显示红色弹出窗口和红色边框,但在我的特定示例中,为简单起见,我不显示它。用户可以通过使用 Tab 键盘按钮或单击 TextBox 等可聚焦的内部控件来调用此状态。
-
InvalidUnfocused - 当控件处于无效状态但未获得焦点时应用。
这里是控件的代码,它只包含一个属性:
public class TestControl : Control
{
public TestControl()
{
this.DefaultStyleKey = typeof(TestControl);
}
public string TestProperty
{
get { return (string)GetValue(TestPropertyProperty); }
set { SetValue(TestPropertyProperty, value); }
}
public static readonly DependencyProperty TestPropertyProperty =
DependencyProperty.Register("TestProperty", typeof(string), typeof(TestControl), new PropertyMetadata(null));
}
之后如果你使用IDataErrorInfo,正确的xaml是:
<local:TestControl TestProperty="{Binding SomeModelProperty, ValidatesOnDataErrors=True}" />
对于INotifyDataErrorInfo,正确的xaml更加简单:
<local:TestControl TestProperty="{Binding SomeModelProperty}" />