日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

[WPF 基础知识系列] —— 绑定中的数据校验Vaildation

發布時間:2023/12/13 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [WPF 基础知识系列] —— 绑定中的数据校验Vaildation 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[WPF 基礎知識系列] —— 綁定中的數據校驗Vaildation 原文:[WPF 基礎知識系列] —— 綁定中的數據校驗Vaildation

前言:

只要是有表單存在,那么就有可能有對數據的校驗需求。如:判斷是否為整數、判斷電子郵件格式等等。

WPF采用一種全新的方式 - Binding,來實現前臺顯示與后臺數據進行交互,當然數據校驗方式也不一樣了。

本專題全面介紹一下WPF中4種Validate方法,幫助你了解如何在WPF中對binding的數據進行校驗,并處理錯誤顯示。

?

一、簡介

正常情況下,只要是綁定過程中出現異常或者在converter中出現異常,都會造成綁定失敗。

但是WPF不會出現任何異常,只會顯示一片空白(當然有些Converter中的異常會造成程序崩潰)。

這是因為默認情況下,Binding.ValidatesOnException為false,所以WPF忽視了這些綁定錯誤。

但是如果我們把Binding.ValidatesOnException為true,那么WPF會對錯誤做出以下反應:

  • 設置綁定元素的附加屬性 Validation.HasError為true(如TextBox,如果Text被綁定,并出現錯誤)。
  • 創建一個包含錯誤詳細信息(如拋出的Exception對象)的ValidationError對象。
  • 將上面產生的對象添加到綁定對象的Validation.Errors附加屬性當中。
  • 如果Binding.NotifyOnValidationError是true,那么綁定元素的附加屬性中的Validation.Error附加事件將被觸發。(這是一個冒泡事件)
  • 我們的Binding對象,維護著一個ValidationRule的集合,當設置ValidatesOnException為true時,

    默認會添加一個ExceptionValidationRule到這個集合當中。

    PS:對于綁定的校驗只在Binding.Mode 為TwoWay和OneWayToSource才有效,

    即當需要從target控件將值傳到source屬性時,很容易理解,當你的值不需要被別人使用時,就很可能校驗也沒必要。

    ?

    二、四種實現方法

    1、在Setter方法中進行判斷

    直接在Setter方法中,對value進行校驗,如果不符合規則,那么就拋出異常。然后修改XAML不忽視異常。

    public class PersonValidateInSetter : ObservableObject{private string name;private int age;public string Name{get { return this.name; }set{if (string.IsNullOrWhiteSpace(value)){throw new ArgumentException("Name cannot be empty!");}if (value.Length < 4){throw new ArgumentException("Name must have more than 4 char!");}this.name = value;this.OnPropertyChanged(() => this.Name);}}public int Age{get{ return this.age; }set{if (value < 18){throw new ArgumentException("You must be an adult!");}this.age = value;this.OnPropertyChanged(() => this.Age);}}}

    ?

    <Grid DataContext="{Binding PersonValidateInSetter}"><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition /></Grid.ColumnDefinitions><TextBlock Text="Name:" /><TextBox Grid.Column="1"Margin="1"Text="{Binding Name,ValidatesOnExceptions=True,UpdateSourceTrigger=PropertyChanged}" /><TextBlock Grid.Row="1" Text="Age:" /><TextBox Grid.Row="1"Grid.Column="1"Margin="1"Text="{Binding Age,ValidatesOnExceptions=True,UpdateSourceTrigger=PropertyChanged}" /></Grid>

    ?

    當輸入的值,在setter方法中校驗時出現錯誤,就會出現一個紅色的錯誤框。

    關鍵代碼:ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged。

    PS:這種方式有一個BUG,首次加載時不會對默認數據進行檢驗。

    ?

    2、繼承IDataErrorInfo接口

    使Model對象繼承IDataErrorInfo接口,并實現一個索引進行校驗。如果索引返回空表示沒有錯誤,如果返回不為空,

    表示有錯誤。另外一個Erro屬性,但是在WPF中沒有被用到。

    public class PersonDerivedFromIDataErrorInfo : ObservableObject, IDataErrorInfo{private string name;private int age;public string Name{get{return this.name;}set{this.name = value;this.OnPropertyChanged(() => this.Name);}}public int Age{get{return this.age;}set{this.age = value;this.OnPropertyChanged(() => this.Age);}}// never called by WPFpublic string Error{get{return null;}}public string this[string propertyName]{get{switch (propertyName){case "Name":if (string.IsNullOrWhiteSpace(this.Name)){return "Name cannot be empty!";}if (this.Name.Length < 4){return "Name must have more than 4 char!";}break;case "Age":if (this.Age < 18){return "You must be an adult!";}break;}return null;}}} <Grid? DataContext="{Binding PersonDerivedFromIDataErrorInfo}"><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition /></Grid.ColumnDefinitions><TextBlock Text="Name:" /><TextBox Grid.Column="1"Margin="1"Text="{Binding Name,NotifyOnValidationError=True,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" /><TextBlock Grid.Row="1" Text="Age:" /><TextBox Grid.Row="1"Grid.Column="1"Margin="1"Text="{Binding Age,NotifyOnValidationError=True,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />

    ?

    PS:這種方式,沒有了第一種方法的BUG,但是相對很麻煩,既需要繼承接口,又需要添加一個索引,如果遺留代碼,那么這種方式就不太好。

    ?

    3、自定義校驗規則

    一個數據對象或許不能包含一個應用要求的所有不同驗證規則,但是通過自定義驗證規則就可以解決這個問題。

    在需要的地方,添加我們創建的規則,并進行檢測。

    通過繼承ValidationRule抽象類,并實現Validate方法,并添加到綁定元素的Binding.ValidationRules中。

    public class MinAgeValidation : ValidationRule{public int MinAge { get; set; }public override ValidationResult Validate(object value, CultureInfo cultureInfo){ValidationResult result = null;if (value != null){int age;if (int.TryParse(value.ToString(), out age)){if (age < this.MinAge){result = new ValidationResult(false, "Age must large than " + this.MinAge.ToString(CultureInfo.InvariantCulture));}}else{result = new ValidationResult(false, "Age must be a number!");}}else{result = new ValidationResult(false, "Age must not be null!");}return new ValidationResult(true, null);}} <Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition /></Grid.ColumnDefinitions><TextBlock Text="Name:" /><TextBox Grid.Column="1" Margin="1" Text="{Binding Name}"></TextBox><TextBlock Grid.Row="1" Text="Age:" /><TextBox Grid.Row="1"Grid.Column="1"Margin="1"><TextBox.Text><Binding Path="Age"UpdateSourceTrigger="PropertyChanged"ValidatesOnDataErrors="True"><Binding.ValidationRules><validations:MinAgeValidation MinAge="18" /></Binding.ValidationRules></Binding></TextBox.Text></TextBox></Grid>

    這種方式,也會有第一種方法的BUG,暫時還不知道如何解決,但是這個能夠靈活的實現校驗,并且能傳參數。

    效果圖:

    ?

    4、使用數據注解(特性方式)

    在System.ComponentModel.DataAnnotaions命名空間中定義了很多特性,

    它們可以被放置在屬性前面,顯示驗證的具體需要。放置了這些特性之后,

    屬性中的Setter方法就可以使用Validator靜態類了,來用于驗證數據。

    public class PersonUseDataAnnotation : ObservableObject{private int age;private string name;[Range(18, 120, ErrorMessage = "Age must be a positive integer")]public int Age{get{return this.age;}set{this.ValidateProperty(value, "Age");this.SetProperty(ref this.age, value, () => this.Age);}}[Required(ErrorMessage = "A name is required")][StringLength(100, MinimumLength = 3, ErrorMessage = "Name must have at least 3 characters")]public string Name{get{return this.name;}set{this.ValidateProperty(value, "Name");this.SetProperty(ref this.name, value, () => this.Name);}}protected void ValidateProperty<T>(T value, string propertyName){Validator.ValidateProperty(value,
    new ValidationContext(this, null, null) { MemberName = propertyName });
    }
    } <Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition /></Grid.ColumnDefinitions><TextBlock Text="Name:" /><TextBox Grid.Column="1"Margin="1" Text="{Binding Name,ValidatesOnExceptions=True,UpdateSourceTrigger=PropertyChanged}" /><TextBlock Grid.Row="1" Text="Age:" /><TextBox Grid.Row="1"Grid.Column="1"Margin="1"Text="{Binding Age,ValidatesOnExceptions=True,UpdateSourceTrigger=PropertyChanged}" /></Grid>

    使用特性的方式,能夠很自由的使用自定義的規則,而且在.Net4.5中新增了很多特性,可以很方便的對數據進行校驗。

    例如:EmailAddress, Phone, and Url等。

    ?

    三、自定義錯誤顯示模板

    在上面的例子中,我們可以看到當出現驗證不正確時,綁定控件會被一圈紅色錯誤線包裹住。

    這種方式一般不能夠正確的展示出,錯誤的原因等信息,所以有可能需要自己的錯誤顯示方式。

    前面,我們已經講過了。當在檢測過程中,出現錯誤時,WPF會把錯誤信息封裝為一個ValidationError對象,

    并添加到Validation.Errors中,所以我們可以取出錯誤詳細信息,并顯示出來。

    1、為控件創建ErrorTemplate

    下面就是一個簡單的例子,每次都把錯誤信息以紅色展示在空間上面。這里的AdornedElementPlaceholder相當于

    控件的占位符,表示控件的真實位置。這個例子是在書上直接拿過來的,只能做基本展示用。

    <ControlTemplate x:Key="ErrorTemplate"><Border BorderBrush="Red" BorderThickness="2"><Grid><AdornedElementPlaceholder x:Name="_el" /><TextBlock Margin="0,0,6,0"HorizontalAlignment="Right"VerticalAlignment="Center"Foreground="Red"Text="{Binding [0].ErrorContent}" /></Grid></Border></ControlTemplate> <TextBox x:Name="AgeTextBox"Grid.Row="1"Grid.Column="1"Margin="1" Validation.ErrorTemplate="{StaticResource ErrorTemplate}" >

    使用方式非常簡單,將上面的模板作為邏輯資源加入項目中,然后像上面一樣引用即可。

    效果圖:

    對知識梳理總結,希望對大家有幫助!

    posted on 2018-09-21 10:24 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

    轉載于:https://www.cnblogs.com/lonelyxmas/p/9685193.html

    總結

    以上是生活随笔為你收集整理的[WPF 基础知识系列] —— 绑定中的数据校验Vaildation的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。