1. 程式人生 > >wpf簡單驗證

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">。就是指定每次輸入字元就驗證一次。