Silverlight:如何在自定义控件中实现验证?

Jon*_*len 5 silverlight

如何在自定义控件中实现验证?我希望复制标准验证逻辑,您将看到TextBox数据绑定到公开IDataErrorInfo或INotifyDataErrorInfo的模型或视图模型.

vor*_*olf 11

要实现验证,您应该将"ValidationStates"组添加到控件的VisualStateManager.

我将TestControlTestProperty属性说明简单的自定义控件.

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>
Run Code Online (Sandbox Code Playgroud)

有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));
}
Run Code Online (Sandbox Code Playgroud)

之后,如果您使用IDataErrorInfo,正确的xaml是:

<local:TestControl TestProperty="{Binding SomeModelProperty, ValidatesOnDataErrors=True}" />
Run Code Online (Sandbox Code Playgroud)

对于INotifyDataErrorInfo,正确的xaml甚至更简单:

<local:TestControl TestProperty="{Binding SomeModelProperty}" />
Run Code Online (Sandbox Code Playgroud)