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

时间:2011-04-07 21:55:16

标签: silverlight

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

1 个答案:

答案 0 :(得分:11)

要实现验证,您应该将“ValidationStates”组添加到控件的VisualStateManager中。

我将使用TestControl属性说明简单的自定义控件TestProperty

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}" />