小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

關(guān)于WPF的驗(yàn)證

 行者花雕 2022-11-15 發(fā)布于北京

1、ValidationRule 驗(yàn)證

ValidationRule:是通過(guò)ValidationRule中的的Validate方法來(lái)驗(yàn)證我們綁定的屬性。所以我們的用法是繼承ValidationRule,重寫他的Validate方法。示例

public class RequiredRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if (value == null)
                return new ValidationResult(false, "不能為空值!");
            if (string.IsNullOrEmpty(value.ToString()))
                return new ValidationResult(false, "不能為空字符串!");

            return new ValidationResult(true, null);
        }
    }

而XAML中需要把錯(cuò)誤信息顯示出來(lái)。

<Window.Resources>
        <ControlTemplate x:Key="ErrorTemplate">
            <Border BorderBrush="Red" BorderThickness="1">
                <AdornedElementPlaceholder/>
            </Border>
        </ControlTemplate>
        <Style TargetType="TextBox">
            <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate}">
            </Setter>
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="True">
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="姓名"/>
        <TextBox>
            <TextBox.Text>
                <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
                    <Binding.ValidationRules>
                        <ValidationRules:RequiredRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <TextBlock Text="年齡"/>
        <TextBox >
            <TextBox.Text>
                <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
                    <Binding.ValidationRules>
                        <ValidationRules:GreaterThanRule Number="10"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </StackPanel>

這樣顯示的錯(cuò)誤信息就會(huì)以 ToolTip和紅色邊框的形式顯示出來(lái)。但這邊如果又在TextBox里面設(shè)置ToolTip那么就會(huì)優(yōu)先選擇TextBox里的,也就是Style中的ToolTip遇到錯(cuò)誤信息是不會(huì)顯示出來(lái)的,而是顯示TextBox中的ToolTip。所以我們可以改善一下顯示的模版來(lái)解決這個(gè)問(wèn)題。

<ControlTemplate x:Key="ErrorTemplate">
            <DockPanel LastChildFill="true">
                <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
                            ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                    <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
                    </TextBlock>
                </Border>
                <AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
                    <Border BorderBrush="red" BorderThickness="1" />
                </AdornedElementPlaceholder>
            </DockPanel>
        </ControlTemplate>

2、Exception 驗(yàn)證

Exception :我們xaml中綁定的對(duì)象是屬性。所以Exception驗(yàn)證,就是通過(guò)屬性的改變來(lái)判斷是否正常。如:

 public int Age
        {
            get { return _age; }
            set
            {
                if (value > 200)
                {
                    throw new Exception("年齡不能大于200");
                }
                _age = value;
            }
        }

同樣跑出的異常在Xaml中也要顯示下。XAML同上。這種方式就會(huì)破壞POCO的設(shè)計(jì)原則。

3、IDataErrorInfo 驗(yàn)證

IDataErrorInfo:這個(gè)驗(yàn)證是通過(guò)我們的實(shí)體對(duì)象繼承IDataErrorInfo來(lái)實(shí)現(xiàn)的。這里聲明的this索引器來(lái)訪問(wèn)類的成員。

 public class BaseDataErrorInfo : IDataErrorInfo
    {
        private string _error;

        public string this[string columnName]
        {
            get { return GetErrorFor(columnName); }
        }

        public string Error
        {
            get { return _error; }
            set { _error = value; }
        }

        public virtual string GetErrorFor(string columnName)
        {
            return string.Empty;
        }
    }
public class Person : BaseDataErrorInfo
    {
        public string Name { get; set; }

        public override string GetErrorFor(string columnName)
        {
            if (columnName == "Name")
                if (string.IsNullOrEmpty(Name))
                    return "Name 不能為空";

            return base.GetErrorFor(columnName);
        }

    }

XAML同上。

4、Custom Control 驗(yàn)證

這里我即不想污染實(shí)體類,又想實(shí)現(xiàn)一個(gè)通用的Validate。我想通過(guò)我xaml綁定的屬性和它所屬的控件。來(lái)顯示ToolTip。

  public abstract class Validator : FrameworkElement
    {
        static Validator()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Validator), new FrameworkPropertyMetadata(typeof(Validator)));
        }

        public virtual string ErrorMessage { get { return string.Empty; } }
        public abstract bool InitialValidation();
        public FrameworkElement ElementName
        {
            get { return (FrameworkElement)GetValue(ElementNameProperty); }
            set { SetValue(ElementNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ElementName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ElementNameProperty =
            DependencyProperty.Register("ElementName", typeof(FrameworkElement), typeof(Validator), new PropertyMetadata(null));


        public object Source
        {
            get { return (object)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Source.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(object), typeof(Validator), new UIPropertyMetadata(new PropertyChangedCallback(ValidPropertyPropertyChanged)));

        private static void ValidPropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var validator = d as Validator;
            if (validator != null)
                validator.SetSourceFromProperty();
            if (string.IsNullOrEmpty(e.NewValue.ToString()))
            {
                if (validator != null)
                {
                    validator.IsValid = validator.InitialValidation();
                    if (validator.ElementName.DataContext != null)
                        validator.ShowToolTip();
                    validator.IsValid = false;
                }
            }
        }

        private void ShowToolTip()
        {
            if (IsValid)
            {
                timer = new DispatcherTimer();
                timer.Interval = TimeSpan.FromSeconds(1.5);
                _toolTip = new ToolTip();
                _toolTip.StaysOpen = true;
                _toolTip.PlacementTarget = ElementName;
                _toolTip.Placement = PlacementMode.Right;

                _toolTip.Content = ErrorMessage;
                _toolTip.IsOpen = true;
                timer.Tick += (sender, args) =>
                                  {
                                      _toolTip.IsOpen = false;
                                      timer.Stop();
                                  };
                timer.Start();
            }

        }
        private void SetSourceFromProperty()
        {
            var expression = this.GetBindingExpression(SourceProperty);
            if (expression != null && this.ElementName == null)
                this.SetValue(Validator.ElementNameProperty, expression.DataItem as FrameworkElement);

        }

        private ToolTip _toolTip;
        private DispatcherTimer timer;

        public bool IsValid { get; set; }
    }

這是一個(gè)簡(jiǎn)單的Validate基類。提供思想。功能不完善。

然后繼承這個(gè)Validator

public class RequiredValidator : Validator
    {
        public override string ErrorMessage { get { return "不能為空值"; } }
        public override bool InitialValidation()
        {
            if (Source == null)
                return false;
            return string.IsNullOrEmpty(Source.ToString());
        }
    }

這里ErrorMessage是顯示錯(cuò)誤信息。

InitialValidation方法是我們要驗(yàn)證的規(guī)則。

代碼

關(guān)于使用的小例子:

一、通過(guò)代碼實(shí)現(xiàn)數(shù)據(jù)綁定

通過(guò)代碼實(shí)現(xiàn)數(shù)據(jù)綁定,使用的是System.Windows.Data命名空間的Binding類,主要使用Binding類的如下的屬性:

  • Source屬性:綁定到的數(shù)據(jù)源
  • Mode屬性:綁定的模式(OneTime、OneWay、TwoWay、OneWayToSource或Default)
  • Path屬性:綁定到的數(shù)據(jù)源的屬性
  • Converter屬性:綁定時(shí)所使用的類型轉(zhuǎn)換器

在綁定目標(biāo)控件上使用SetBinding方法添加數(shù)據(jù)綁定。例如將MyData的Name屬性綁定到txtName控件的Text屬性上,使用MyColorConverter轉(zhuǎn)換器將MyBindingColor的ColorObject屬性綁定到rec控件的Fill屬性上:

   1: MyData data = new MyData();
   2:  
   3: Binding binding1 = new Binding();
   4: binding1.Source = data;
   5: binding1.Mode = BindingMode.OneWay;
   6: binding1.Path = new PropertyPath("Name");
   7:  
   8: txtName.SetBinding(TextBox.TextProperty, binding1);
   9:  
  10:  
  11: MyBindingColor color = new MyBindingColor();
  12:  
  13: Binding binding2 = new Binding();
  14: binding2.Source = color;
  15: binding2.Mode = BindingMode.OneWay;
  16: binding2.Path = new PropertyPath("ColorObject");
  17: binding2.Converter = new MyColorConverter();
  18:  
  19: rec.SetBinding(Rectangle.FillProperty, binding2);

二、實(shí)現(xiàn)綁定數(shù)據(jù)的驗(yàn)證:

對(duì)于綁定數(shù)據(jù)的驗(yàn)證,系統(tǒng)采用如下的機(jī)制:

DataBindingValidation

使用 WPF 數(shù)據(jù)綁定模型可以將 ValidationRules 與 Binding 對(duì)象相關(guān)聯(lián)。當(dāng)綁定目標(biāo)的屬性向綁定源屬性傳遞屬性值時(shí)(僅限TwoWay模式或OneWayToSource模式),執(zhí)行ValidationRule中的Validate方法,實(shí)現(xiàn)對(duì)界面輸入數(shù)據(jù)的驗(yàn)證。

定義驗(yàn)證可以采用以下三種:

  • DataErrorValidationRule:檢查由源對(duì)象的 IDataErrorInfo 實(shí)現(xiàn)所引發(fā)的錯(cuò)誤,要求數(shù)據(jù)源對(duì)象實(shí)現(xiàn)System.ComponentModel命名空間的IDataErrorInfo接口。

例如,定義一個(gè)學(xué)生信息類,要求其學(xué)生成績(jī)?cè)?到100間,學(xué)生姓名的長(zhǎng)度在2到10個(gè)字符間:

   1: public class StudentInfoWithValidation : IDataErrorInfo
   2: {
   3:     #region 構(gòu)造方法
   4:     public StudentInfoWithValidation()
   5:     {
   6:         StudentName = "Tom";
   7:         Score = 90;
   8:     }
   9:     public StudentInfoWithValidation(string m_StudentName,double m_Score)
  10:     {
  11:         StudentName = m_StudentName;
  12:         Score = m_Score;
  13:     }
  14:     #endregion
  15:  
  16:     #region 屬性
  17:     public string StudentName
  18:     {
  19:         get; set;
  20:     }
  21:     public double Score
  22:     {
  23:         get; set;
  24:     }
  25:     #endregion
  26:  
  27:     #region 實(shí)現(xiàn)IDataErrorInfo接口的成員
  28:     public string Error
  29:     {
  30:         get 
  31:         {
  32:             return null;
  33:         }
  34:     }
  35:  
  36:     public string this[string columnName]
  37:     {
  38:         get
  39:         {
  40:             string result = null;
  41:  
  42:             switch (columnName)
  43:             {
  44:                 case "StudentName":
  45:                     // 設(shè)置StudentName屬性的驗(yàn)證規(guī)則
  46:                     int len = StudentName.Length;
  47:                     if (len < 2 || len > 10)
  48:                     {
  49:                         result = "StudentName length must between 2 and 10";
  50:                     }
  51:                     break;
  52:                 case "Score":
  53:                     // 設(shè)置Score屬性的驗(yàn)證規(guī)則
  54:                     if (Score < 0 || Score > 100)
  55:                     {
  56:                         result = "Score must between 0 and 100";
  57:                     }
  58:                     break;
  59:             }
  60:  
  61:             return result;
  62:         }
  63:     }
  64:     #endregion
  65: }

在界面上,定義兩個(gè)TextBox綁定到StudentName和Score兩個(gè)屬性上,并設(shè)置其采用DataErrorValidationRule:

   1: <Window x:Class="WPFDataBindingDemo.WinDataErrorValidationRuleDemo"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:local="clr-namespace:WPFDataBindingDemo"
   5:     Title="WinDataErrorValidationRuleDemo" Height="154" Width="300">
   6:     <Canvas Height="116" x:Name="mainCanvas">
   7:         <Canvas.Resources>
   8:             <local:StudentInfoWithValidation x:Key="myData" />
   9:         </Canvas.Resources>
  10:         <Canvas.DataContext>
  11:             <Binding Source="{StaticResource myData}" />
  12:         </Canvas.DataContext>
  13:         <Label Canvas.Left="10" Canvas.Top="10" Height="28" Name="label1" Width="120">StudentName:</Label>
  14:         <Label Canvas.Left="10" Canvas.Top="36" Height="28" Name="label2" Width="120">Score:</Label>
  15:         <TextBox Canvas.Left="136" Canvas.Top="12" Height="23" Name="textBox1" Width="120">
  16:             <TextBox.Text>
  17:                 <Binding Path="StudentName" 
  18:                          Mode="TwoWay" 
  19:                          UpdateSourceTrigger="PropertyChanged"
  20:                          ValidatesOnDataErrors="True" />
  21:             </TextBox.Text>
  22:         </TextBox>
  23:         <TextBox Canvas.Left="136" Canvas.Top="41" Height="23" Name="textBox2" Width="120">
  24:             <TextBox.Text>
  25:                 <Binding Path="Score" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
  26:                     <!--與上一個(gè)TextBox控件的寫法作用相同-->
  27:                     <Binding.ValidationRules>
  28:                         <DataErrorValidationRule />
  29:                     </Binding.ValidationRules>
  30:                 </Binding>
  31:             </TextBox.Text>
  32:         </TextBox>
  33:         <Button Canvas.Left="12" Canvas.Top="79" Height="23" Name="button1" Width="118" Click="button1_Click">Get Student Info</Button>
  34:         <Button Canvas.Left="136" Canvas.Top="79" Height="23" Name="button2" Width="118" Click="button2_Click">Get Validate State</Button>
  35:     </Canvas>
  36: </Window>

22-2 22-3

22-4 22-5

從執(zhí)行的結(jié)果上來(lái)看,當(dāng)驗(yàn)證出現(xiàn)錯(cuò)誤(即索引器屬性返回的字符串不為空時(shí)),系統(tǒng)默認(rèn)給出一種驗(yàn)證錯(cuò)誤的顯示方式(控件以紅色邊框包圍),但是需注意兩點(diǎn):

    • 產(chǎn)生驗(yàn)證錯(cuò)誤,驗(yàn)證后的數(shù)據(jù)仍然會(huì)更改數(shù)據(jù)源的值
    • 如果系統(tǒng)出現(xiàn)異常,如成績(jī)值輸入 “90d”,則系統(tǒng)不會(huì)顯示錯(cuò)誤,控件上的輸入值也不賦值到數(shù)據(jù)源。這種情況下,需要使用ExceptionValidationRule。
  • ExceptionValidationRule:即當(dāng)綁定目標(biāo)的屬性值向綁定源的屬性值賦值時(shí)引發(fā)異常所產(chǎn)生的驗(yàn)證。此種方式若實(shí)現(xiàn)自定義的邏輯驗(yàn)證,通常設(shè)置數(shù)據(jù)源的屬性的Set訪問(wèn)器,在Set訪問(wèn)器中,根據(jù)輸入的值結(jié)合邏輯,使用throw拋出相應(yīng)的異常。

例如上例中,對(duì)于Score對(duì)應(yīng)的TextBox,再加入ExceptionValidationRule:

   1: <TextBox Canvas.Left="136" Canvas.Top="41" Height="23" Name="textBox2" Width="120">
   2:     <TextBox.Text>
   3:         <Binding Path="Score" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
   4:             <!--與上一個(gè)TextBox控件的寫法作用相同-->
   5:             <Binding.ValidationRules>
   6:                 <DataErrorValidationRule />
   7:                 <ExceptionValidationRule />
   8:             </Binding.ValidationRules>
   9:         </Binding>
  10:     </TextBox.Text>
  11: </TextBox>

22-6

  • 自定義驗(yàn)證規(guī)則:定義一個(gè)類,繼承ValidationRule抽象類,實(shí)現(xiàn)其Validate方法,驗(yàn)證某一輸入。

 

 

 

 

 

 

 

例如,定義一個(gè)類,用來(lái)驗(yàn)證輸入的Email地址是否合法(驗(yàn)證的Email允許為字符串的空值String.Empty,但有輸入必須符合Email的格式要求)

在學(xué)生類中添加Email可讀可寫屬性(并不做相應(yīng)的驗(yàn)證,忽略其他重復(fù)代碼):

   1: public string Email
   2: {
   3:     set; get;
   4: }

定義一個(gè)類,實(shí)現(xiàn)Email格式驗(yàn)證:

   1: using System.Globalization;
   2: using System.Text.RegularExpressions;
   3: using System.Windows.Controls;
   4:  
   5: namespace WPFDataBindingDemo
   6: {
   7:     public class EmailValidationRule : ValidationRule
   8:     {
   9:         public override ValidationResult Validate(object value, CultureInfo cultureInfo)
  10:         {
  11:             bool isValid = false;
  12:             string message = null;
  13:  
  14:             // 檢查輸入值不為空,且是字符串
  15:             if (value != null && value is string)
  16:             {
  17:                 string email = value.ToString();
  18:  
  19:                 // 檢查輸入的字符串是否為String.Empty
  20:                 if (email != string.Empty)
  21:                 {
  22:                     string emailFormartRegex =
  23:                         @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|" +
  24:                         @"(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
  25:                     
  26:                     // 檢查輸入的字符串是否符合Email格式
  27:                     isValid = Regex.IsMatch(email, emailFormartRegex);
  28:  
  29:                     if (! isValid)
  30:                     {
  31:                         message = "Input string not match Email Format";
  32:                     }
  33:                 }
  34:                 else
  35:                 {
  36:                     // 輸入的字符串為字符串空值時(shí),認(rèn)為驗(yàn)證通過(guò)
  37:                     isValid = true;
  38:                 }
  39:             }
  40:             else
  41:             {
  42:                 message = "Input value is NULL or is not string.";
  43:             }
  44:  
  45:             // 返回驗(yàn)證結(jié)果(ValidationResult對(duì)象)
  46:             return new ValidationResult(isValid,message);
  47:         }
  48:     }
  49: }

在界面上:

   1: <TextBox Canvas.Left="104" Canvas.Top="70" Height="23" Name="textBox3" Width="152">
   2:     <Binding Mode="TwoWay" Path="Email" UpdateSourceTrigger="PropertyChanged">
   3:         <Binding.ValidationRules>
   4:             <local:EmailValidationRule />
   5:         </Binding.ValidationRules>
   6:     </Binding>
   7: </TextBox>

22-7

 

 

 

三、為數(shù)據(jù)驗(yàn)證提供視覺(jué)效果

在數(shù)據(jù)驗(yàn)證錯(cuò)誤后,可以通過(guò)以下兩種方式提供相應(yīng)的視覺(jué)效果:

  • 定義Style及相應(yīng)的觸發(fā)器

如果要使輸入的控件的外觀發(fā)生變化,可以使用Style。例如上例中出錯(cuò),使輸入的文本框的背景顏色和字體顏色發(fā)生變化,并提供ToolTip顯示錯(cuò)誤信息,可以定義如下的Style:

   1: <Style TargetType="TextBox">
   2:     <Setter Property="Background" Value="White" />
   3:     <Setter Property="Foreground" Value="Black" />
   4:     <Style.Triggers>
   5:         <Trigger Property="Validation.HasError" Value="True">
   6:             <Setter Property="Background" Value="#DDD" />
   7:             <Setter Property="Foreground" Value="Red" />
   8:             <Setter Property="ToolTip"
   9:                     Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}"/>
  10:         </Trigger>
  11:     </Style.Triggers>
  12: </Style>

效果如下:

 22-8

  • 定義控件模板

如果要為相應(yīng)的控件添加一些輔助的控件,可以使用控件模板,如出現(xiàn)驗(yàn)證錯(cuò)誤時(shí),不使用系統(tǒng)默認(rèn)的紅色邊框,而是在文本框后添加一個(gè)紅色的星號(hào):

   1: <ControlTemplate x:Key="validErrorTextBoxTemplate">
   2:     <DockPanel>
   3:         <AdornedElementPlaceholder/>
   4:         <TextBlock Foreground="Red" FontSize="20">*</TextBlock>
   5:     </DockPanel>
   6: </ControlTemplate>

并在每一個(gè)輸入的TextBox中添加:

   1: Validation.ErrorTemplate="{StaticResource validErrorTextBoxTemplate}"

22-9

轉(zhuǎn)自:https://www.cnblogs.com/fuchongjundream/p/3844051.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多