zoukankan      html  css  js  c++  java
  • wpf验证方案讨论

          虽然wpf内部有验证方案,但在实际应用中,会出现一些问题.这里发出来与大家共同讨论.作为使用者,你喜欢哪一种呢?这里不解释数据绑定的知识,因为不够专业,怕会误导,索性不写.但我相信大家会遇到这个问题.本文是通过多个示例比较得出的想法.

    1.通过继承ValidationRule抽象类,定义验证规则重写Validate方法

    这里是sdk的示例代码

    Code

    然后是xaml的使用代码

        <TextBox Name="textBox1" Width="50" FontSize="15"
                 Validation.ErrorTemplate
    ="{StaticResource validationTemplate}"
                 Style
    ="{StaticResource textBoxInError}"
                 Grid.Row
    ="1" Grid.Column="1" Margin="2">
          
    <TextBox.Text>
            
    <Binding Path="Age" Source="{StaticResource ods}"
                     UpdateSourceTrigger
    ="PropertyChanged" >
              
    <Binding.ValidationRules>
                
    <c:AgeRangeRule Min="21" Max="130"/>
              
    </Binding.ValidationRules>
            
    </Binding>
          
    </TextBox.Text>
        
    </TextBox>

    就是通过ValidationRules集合挂验证规则.如果逻辑不复杂的话,勉强可以接受,这里我个人认为可以作为界面的验证.但如果业务逻辑一旦发生变化,则意味着xaml文件一直需要修改,这并不是一种好的做法,并不推荐.(而且内置的验证规则太少了,有的话还勉强用用,都需要自己重写)

    2.通过正则表达式附加属性简化写法,大家应该知道,验证部分,正则表达式占了很大部分.

    定义一个正则表达式类,然后通过附加属性进行验证.具体的方案,请参考这里
    http://www.codeproject.com/WPF/RegexValidationInWPF.asp
    然后前端xaml的使用方法
        <TextBox
          
    Text="{Binding Path=EmailAddress, UpdateSourceTrigger=PropertyChanged}" 
          jas:RegexValidator.RegexText
    ="^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$" 
          jas:RegexValidator.ErrorMessage
    ="Invalid e-mail address." 
          
    />

    代码是简化了,但有个缺点,只能定义一个验证规则,也存在着我上面提到的问题,把正则写在ui上面,并不是一个好的做法,应该对其进行封装(看着这么多符号就心慌,高手可以这么做),也并不推荐的做法.

    3.与业务逻辑验证绑定在一起
    这种做法与上面的都不同,因为业务逻辑的判断与常规的判断比如(比如是否必填,字符匹配等),而且前端只需要绑定字段就可以了,先看前端的做法
    <TextBox Width="100" Grid.Column="1" HorizontalAlignment="Left" Margin="5,5,0,5" x:Name="txtFirstName" Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}" ToolTip="Enter customers first name." />

    请注意,这里并没有写什么验证规则或正则表达式哦,真正的验证在这里,验证的对象必须实现IDataErrorInfo接口,通过索引器,可以判断对象的每个字段.
    上面紧紧是FirstName,这里是通过整个对象的业务逻辑判断的,否则你需要在ui上面都定义一个验证规则,非常麻烦(比如有2个字段,你必须对两个字段都定义验证规则(即第一种方法)).这种做法是比较好的,把逻辑与ui分开了,值得推荐.sdk示例代码
     public class Person : IDataErrorInfo
        
    {
            
    private int age;

            
    public int Age
            
    {
                
    get return age; }
                
    set { age = value; }
            }


            
    public string Error
            
    {
                
    get
                
    {
                    
    return null;
                }

            }


            
    public string this[string name]
            
    {
                
    get
                
    {
                    
    string result = null;

                    
    if (name == "Age")
                    
    {
                        
    if (this.age < 0 || this.age > 150)
                        
    {
                            result 
    = "Age must not be less than 0 or greater than 150.";
                        }

                    }

                    
    return result;
                }

            }

        }


    但还有些问题,如果我在第3点的基础上,我还要加一个普通的判断,比如必填验证,长度验证,还是逃不了验证规则这一步.
    这里我们要做出选择
    把规则定义在ui上(变动太大,不适合,无奈之举)
    写在业务逻辑里面(这样下来,逻辑未免太复杂)

    4.以元数据的形式(在属性上挂标签)

    codeproject上,我找到一个比较完美的解决方案,作者自己重新定义了一套标签,使用也比较简单(代码是vb的,编译后再反编译用c#看:)),这种做法已经接近了要求.大家去看看这篇文章,非常的不错.其在还为前端提供了一个ui显示错误的一个下拉列表.不过通过这个例子,我又想到一个更好的东西.

    5.使用EnterPrise Library Validation Application Block(再好不过)
    由于wpf的属性使用了大量的依赖属性,我原以为这个好东西在wpf算是废了,通过第3点和第4点,我们终于可以引进这个企业级模块了。如下做法
    Code

    然后继承之,随便定一个对象来demo
       public class aa:BaseValidationEntity<aa>
        
    {
            
    private string firstName;

            [StringLengthValidator(
    410,MessageTemplate="aaa")]
            [RegexValidator(
    @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", MessageTemplate = "Invalid e-mail address")]
            
    public string FirstName
            
    {
                
    get return firstName; }
                
    set { firstName = value;
                OnPropertyChanged(
    "FirstName");
                }

            }

        }

    我们看到熟悉的标签了,目前我认为这种方案最好,当然我们也可以通过配置xml来实现,这样真正做到了界面与逻辑分离。

    上面一层的做到了逻辑上的验证,至于界面如何显示错误,我们可以通过Error属性来定制一个控件,这个暂不讨论了

    在学习wpf的朋友,欢迎一起讨论。

     参考文章
    http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
  • 相关阅读:
    Kali学习笔记38:文件上传漏洞
    Kali学习笔记37:APPSCAN
    Kali学习笔记36:AVWS10的使用
    Kali学习笔记35:使用VBScript、PowerShell、DEBUG传输文件
    Kali学习笔记34:配置TFTP和FTP服务
    《day13--异常的进阶和包的使用》
    《java作业》
    《day12---异常》
    《AppletButtonEvent.java》
    《CheckboxDemo.java》
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/wpfvalidation.html
Copyright © 2011-2022 走看看