WPF 中TextBox 增加输入检测,错误提示

先来总结下实现错误提示功能的几个要点

1:binding 的ValidationRules

2 :Validation.ErrorTemplate

 

首先我们在界面添加一个TextBox, Text绑定到people对象的属性age

public class People
{
public int age { get; set; }
public string name { get; set; }
}

        <TextBox x:Name="textBox"   HorizontalAlignment="Left" Height="30" Margin="75,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="155">
            <TextBox.Text>
                <Binding  UpdateSourceTrigger="PropertyChanged" Source="{StaticResource people}" Path="age" >
                    <Binding.ValidationRules>
                        <local:AgeValidationRule ></local:AgeValidationRule>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

这里我们binding.ValidationRules 添加一个自己写的错误验证规则AgeValidationrule 代码如下

    public class AgeValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            int ret = 0;
            if(!int.TryParse(value.ToString(),out ret))
                return new ValidationResult(false, "不是有效的数字");
            if( ret >130 || ret<1)
                return new ValidationResult(false, "年龄必须是1-130之间");
            return new ValidationResult(true, "");
        }
    }

这样,当Text的值变化时,就会触发binding的验证规则,调用到这里面的validate函数。函数的第一个参数value传的是我们绑定的值,第二个是时区信息,这里我们不用管第二个。

此时,我们的TextBox已经有了自我检查的能力。比如输入一个a ,a不是数字,触发validate函数时,验证返回错误信息

ValidationResult(false, "不是有效的数字")

可以看到框框变红了。这是因为使用了TextBox自带默认的errorTemplate.

这样的提示不够明显,还达不到我们的要求

下面我们来自己动手做一个错误提示模板

            <Validation.ErrorTemplate>
                <ControlTemplate>
                    <StackPanel Orientation="Horizontal">
                        <AdornedElementPlaceholder Name="customAdorner"></AdornedElementPlaceholder>
                        <TextBox Text="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Margin="10,0,0,0" BorderBrush="Red" Foreground="Red" VerticalContentAlignment="Center" >
                        </TextBox>
                    </StackPanel>
                </ControlTemplate>
            </Validation.ErrorTemplate>

分析一下这里的代码,Validation.ErrorTemplate,作为一个附加属性,绑在TextBox上,当TextBox的Text 改变时,触发binding的验证规则 ValidationRules 。会调用到里面对应的validate函数。

如果该函数返回结果为错误。那么这个ErrorTemplate 就会显示出来。

ErrorTemplate 中有一个很有意思的控件 AdornedElementPlaceholder ,它代表了整个ErrorTemplate 的宿主。假设我有一个名为XXX的控件,设置XXX的ErrorTemplate为上面的ErrorTemplate。那么这个AdornedElementPlaceholder 就代表了这个XXX控件。这样,我的ErrorTemplate就可以根据XXX控件的位置,来定位出StackPanel 和ErrorTemplate中textbox的位置。

即定位了我的错误提示内容的位置。

 

好,我们看到TextBox可以设置自己的附加属性Validation.ErrorTemplate,应该说整个Validation都可以看成TextBox的附加属性。那么这个Validation里还有一些我们能用到的东西。

当Bingding的验证触发后,会把里面的错误信息保存到这个Validation的Errors列表中。这样,我们就可以取出里面的错误信息。即Validate函数返回的年龄必须是1-130之间。

所以,我们把错误提示用的TextBox的Text绑定到它的AdornedElementPlaceholder 对应控件的(Validation.Errors)[0].ErrorContent

 

Text="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"

至此,大功告成

看一下效果

 源码路径 : https://files.cnblogs.com/files/CSSZBB/TextBoxErrorHint.zip

posted on 2018-07-26 19:27  陈傻傻周笨笨  阅读(4294)  评论(0编辑  收藏  举报

导航