wpf簡單驗證
WPF快速指導5:驗證
本文摘要:
1:WPF中的驗證處理機制;
2:自定義驗證規則;
3:如何顯示驗證錯誤資訊
4:指定何時進行驗證
1:WPF中的驗證處理機制
接受使用者輸入的大多數應用程式都需要具有驗證邏輯,以確保使用者輸入了需要的資訊。驗證檢查可以基於型別、範圍、格式或其他應用程式特定的要求。本節討論了資料驗證在 WPF 中的工作方式。
先來看一個簡單的例子
<Window.Resources> <local:Person x:Key="luminji" Name="luminji"Age="3"></local:Person> </Window.Resources> <StackPanel DataContext="{StaticResource luminji}" > <TextBox x:Name="textBoxAge"> <TextBox.Text> <Binding Path="Age" NotifyOnValidationError="True"> <Binding.ValidationRules> <ExceptionValidationRule></ExceptionValidationRule> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <Button>Button</Button> </StackPanel>
後臺:
public partial class Window1 : Window { public Window1() { InitializeComponent(); Validation.AddErrorHandler(this.textBoxAge, delegate(object sender, ValidationErrorEventArgs e) { MessageBox.Show(e.Error.ErrorContent.ToString()); }); } } class Person { public string Name { get; set; } public int Age { get; set; } }
WPF中的驗證處理機制是:當驗證結果出現非法資料時,就會產生一個包含錯誤資訊的ValidationError物件供介面進行顯示。在使用了ExceptionValidationRule的情況下,這個錯誤物件會包含驗證規則所捕獲到的Exception物件的Message屬性。當然,為了,訪問到這個異常,我們需要為頁面的Validation物件新增附件事件,即上文中Validation.AddErrorHandler(……)。注意,為了能捕獲這個事件,還需要將資料繫結中的NotifyOnValidationError設定為True。
把這段程式碼執行起來,如果你在文字框中輸入的不是數字,則會彈出ExceptionValidationRule中預設的“輸入字串的格式不正確”。但是顯然,這種系統預設提供給我們的提示資訊不能滿足我們的要求。如果要對錯誤進行更多的自定義處理,首先就要自定義驗證規則。
2:自定義驗證規則
自定義驗證規則需要繼承抽象類ValidationRule,並重寫Validate方法。然後在XAML中的ExceptionValidationRule換成自定義的驗證規則類就行。
前臺中相應替換的內容:
<TextBox.Text> <Binding Path="Age" NotifyOnValidationError="True"> <Binding.ValidationRules> <local:AgeRule></local:AgeRule> </Binding.ValidationRules> </Binding> </TextBox.Text>
後臺的自定義驗證類:
class AgeRule: ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { int number; if (!int.TryParse((string)value, out number)) { return new ValidationResult(false, "輸入的內容必須為數字!"); } else if( number > 100 || number < 0) { return new ValidationResult(false, "輸入的年齡超過範圍"); } else { //return new ValidationResult(true, null); return ValidationResult.ValidResult; } } }
我們注意到,上文中的100和0是硬編碼,還有一種雖然是前臺硬編碼,但是看上去要舒服很多,見下文:
前臺中相應替換的內容:
<TextBox.Text> <Binding Path="Age" NotifyOnValidationError="True"> <Binding.ValidationRules> <local:AgeRule Max="100" Min="0"></local:AgeRule> </Binding.ValidationRules> </Binding> </TextBox.Text>
後臺中相應變化的內容:
class AgeRule: ValidationRule { public int Min { get; set; } public int Max { get; set; } public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { int number; if (!int.TryParse((string)value, out number)) { return new ValidationResult(false, "輸入的內容必須為數字!"); } else if( number > Max || number < Min) { return new ValidationResult(false, "輸入的年齡超過範圍"); } else { //return new ValidationResult(true, null); return ValidationResult.ValidResult; } } }
3:如何顯示驗證錯誤資訊
在上文中,我們通過MessageBox來顯示驗證的錯誤資訊。看上去有點業餘,即使用者友好度不夠,更好的處理方法是在UI上指定一個固定的區域進行顯示。指定固定區域進行顯示有三種方法。
第一種,是在Validation.AddErrorHandler為某個區域賦值錯誤資訊。如下文程式碼中的textBlockErrorMessage0。
第二種,是為區域繫結錯誤資訊,如下文程式碼中的textBlockErrorMessage1。
第三種,是為Validation.HasError設定觸發器,指定Validation.ErrorTemplate來動態顯示錯誤資訊。
提倡第三種做法。
前臺程式碼:
<Window.Resources> <local:Person x:Key="luminji" Name="luminji" Age="3"></local:Person> <Style TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <DockPanel LastChildFill="True"> <TextBlock DockPanel.Dock="Right" Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"> </TextBlock> <Border BorderBrush="Red" BorderThickness="1"> <AdornedElementPlaceholder Name="MyAdorner"/> </Border> </DockPanel> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel DataContext="{StaticResource luminji}" > <TextBox x:Name="textBoxAge" Width="100"> <TextBox.Text> <Binding Path="Age" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:AgeRule Max="100" Min="0"></local:AgeRule> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBlock x:Name="textBlockErrorMessage0"/> <TextBlock x:Name="textBlockErrorMessage1" Text="{Binding ElementName=textBoxAge, Path=(Validation.Errors)[0].ErrorContent}" /> <Button>Button</Button> </StackPanel>
後臺程式碼程式碼因為和上文的後臺程式碼沒有太多區別,故略。
值得注意的是,前臺程式碼的觸發器中,<TextBlock DockPanel.Dock="Right" Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">,AdornedElement這個屬性不能少。AdornedElement表示的是當前裝飾器所在的UIElement。
4:指定何時進行驗證
上文的例子中,我們都是在文字框失去焦點的時候看到驗證的錯誤資訊的。我們還可以指定這個驗證的時機,就是為文字框的繫結設定UpdateSourceTrigger。如:<Binding Path="Age" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">。就是指定每次輸入字元就驗證一次。