數據綁定-驗證(二)

在數據綁定時,還有一項工作,就是數據的驗證。

在上一篇博文中,文本框來顯示person對象的年齡,我們知道,因爲年齡是數據,在輸入非數字時,一定是不符合現實意義的。在WPF中,對數據的綁定,特別是雙向綁定,數據目標屬性更新數據源屬性時,進行數據驗證,道先,如果給一個綁定目標屬性加入驗證,必需用屬性元素語法來達到目的,就是給Binding屬性添加一個<Binding.ValudationRules>,再添加一個<ExceptionValidationRule>的子標籤,同時把<Binding>標籤的NotifyOnValidationError的屬性設置成true,這樣,後臺的驗證代碼才起作用(因爲默認情況下NotifyOnValidationError是 false)

<TextBox Height="23" Margin="12,31,0,0" Name="textBox1" ;120" >

<TextBox.Text>

<Binding Path="Age" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">

<Binding.ValidationRules>

<ExceptionValidationRule>

</ExceptionValidationRule>

</Binding.ValidationRules>

</Binding>

</TextBox.Text>

</TextBox>

上面XAML代碼與下面代碼功能相同:

Binding bd = new Binding("Age");

bd.Mode = BindingMode.TwoWay;

bd.NotifyOnValidationError = true;

bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

ValidationRule vr = new ExceptionValidationRule();

bd.ValidationRules.Add(vr);

textBox1.SetBinding(TextBox.TextProperty, bd);

然後把驗證失敗後的執行操作代碼,關聯起來,如下:

Validation.AddErrorHandler(textBox1, valite);

//下面是驗證失敗後的代碼。

public void valite(object sender, ValidationErrorEventArgs e)

{

if (e.Action == ValidationErrorEventAction.Added)

{

MessageBox.Show((string)e.Error.ErrorContent, "驗¨|證?è錯?¨a誤¨?!ê?");

}

}

在驗證數據時,我們用的是系統自定義的驗證類ValidationRule,這個類是個抽象類,目前的版本微軟提供了兩個子類來實現它,一個是ExceptionValidationRule,另一個是DataErrorValidationRule,前者是捕獲在綁定目標屬性把數據更新回綁定源屬性時的異常,後者是檢查綁定源提供用戶界面可以綁定的自定義錯誤信息。本例子中,用的是ExceptionValidationRule,實際上就是把一些非int類型的數值給person.Age賦值時,觸發異常,ExceptionValidationRule就捕獲到異常,從而通過Validation.AddErrorHandler來報出異常。

另外,即然ValidationRule是抽象類,ExceptionValidationRule和DataErrorValidationRule都是繼承它來的,能不能我們也定義一個類去繼承ValidationRule,來完成自己的驗證呢,答案是肯定的,就拿上面的例子來說Age,一般是在0到150之間(人的年齡一般沒有負的,人的年齡指活的時長,也就是人最多活150歲,這個值已經相當對得起活着的人了),那就可以自定義一個類,繼承ValidationRule,來實現這個年齡範圍的業務。

首先來定義這個類:

public class ValidationAge:ValidationRule

{

public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)

{

int age;

if (!int.TryParse(value.ToString(), out age))

{

return new ValidationResult(false, "年齡類型不正確!");

}

else

{

if (age < 0 || age > 150)

{

return new ValidationResult(false, "不符合人類的年齡(0-150)!");

}

else

{

return new ValidationResult(true, null);

}

}

}

}

XAML代碼如下:

<TextBox Height="23" Margin="12,31,0,0" Name="textBox1" ;120" >

<TextBox.Text>

<Binding Path="Age" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">

<Binding.ValidationRules>

<m:ValidationAge>

</m:ValidationAge>

</Binding.ValidationRules>

</Binding>

</TextBox.Text>

</TextBox>

或用代碼實現:

Binding bd = new Binding("Age");

bd.Mode = BindingMode.TwoWay;

bd.NotifyOnValidationError = true;

bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

ValidationRule vr = new ValidationAge();

bd.ValidationRules.Add(vr);

textBox1.SetBinding(TextBox.TextProperty, bd);

如果拋開WPF綁定這個概念,上面所做的工作就是從UI的值往對象中回寫的時候,如果不符合要求,就拋出異常,在 WinForm中,我們通常是給類的屬性設置這些驗證,就是在Person類的Age屬性Set訪問器中驗證Value的有效性,當然,這種做完在WPF中也有效,相經較之下,這種做法還較簡單。其實WPF中的這種做法,本質是一樣的,就在是調用Person類的Age的Set訪問器前,加了一個驗證。

還有一點要注意的是在驗證方法valite中,ValidationErrorEventArgs參數有一個Action的屬性,這個屬性是個枚舉值,有兩個枚舉值,Added和Removed,如果不作處理,當我們輸入一個非數字的值時,理所當然報錯,但當我們刪除這個值時也報錯,就是因爲才望高驗證的觸發是驗證值的改變,添加和刪除(沒有修改,因爲修改是一個刪除+添加的過程),所以爲了避免出來兩次驗證,就作了一下處理,只驗證Action爲Added的。

再有一點就是,如果綁定不做自定義驗證VlidationAge,而是用ExceptionValidationRule,文本框與年齡綁定,因爲年齡是整型,如果在文本框中輸和e或E,都會轉化成科學講學法的,這點要注意。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章