WPF Binding Validation 數據驗證


表單的數據驗證往往枯燥無味,又不可避免.
在一個如下表單只有兩個輸入框,和確定按鈕的情況下,正常我們需要做哪些工作呢?
validation

 

1. 如果年齡輸入框輸入了非數字的字符串,輸入框失去焦點后,后面錯誤消息應當能立即提示出來

2.錯誤的提示的內容如果變化,你可能需要修改整個UI設計.(如顯示在輸入框下方)

3.點擊OK按鈕,需要遍歷Window所有輸入框,如果有輸入數據驗證不符合,需要提示錯誤,並將對應的控件獲取焦點.

這很容易么?當這個輸入框再多一些呢?

下面的Demo,看在WPF如何輕松處理這些:

validation2

Window里,textBox1,textBox2,textBox3 綁定的數據為:

DataSource
  • 使用自定義驗證規則
<TextBox Name="textBox1" Width="50" FontSize="15"
         Validation.ErrorTemplate="{StaticResource validationTemplate}"
         Style="{StaticResource textBoxInError}"
         Grid.Row="1" Grid.Column="1" Margin="2">
  <TextBox.Text>
    <Binding Path="Age" Source="{StaticResource ods}"
             UpdateSourceTrigger="PropertyChanged" >
      <Binding.ValidationRules>
        <c:AgeRangeRule Min="21" Max="130"/>
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>
 

textBox1 綁定了Age ,並且使用的驗證的規則為 AgeRangeRule ,規則中指定了最小值和最大值,當PropertyChanged時驗證規則將觸發,也就是該控件失去焦點之時. 提示的信息樣式定義在ErrorTemplate里,讓我們再來看一看ErrroTemplate的內容:

      <ControlTemplate x:Key="validationTemplate">
        <DockPanel>
          <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
          <AdornedElementPlaceholder/>
        </DockPanel>
      </ControlTemplate>


AdornedElementPlaceholder 才是這里的點睛之處,此處放置了待驗證的控件,而整個ErrorTemplate正是使用神奇的Adoner實現了錯誤的提示的位置和原排版布局的無關性. 驗證規則和整個代碼完全解耦:

rule

驗證規則驗證失敗時候拋出的異常顯示在Tip里.

     <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
        <Style.Triggers>
          <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip"
              Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                              Path=(Validation.Errors)[0].ErrorContent}"/>
          </Trigger>
        </Style.Triggers>
      </Style>
  • 使用ExceptionValidationRule


另一種方法,不自定義Rule,如:

 <TextBox Name="textBox3" Width="50" FontSize="15"
             Grid.Row="5" Grid.Column="1" Margin="2"
             Validation.ErrorTemplate="{StaticResource validationTemplate}"
             Style="{StaticResource textBoxInError}">
      <TextBox.Text>
        <Binding Path="Age3" Source="{StaticResource ods}"
                 UpdateSourceTrigger="PropertyChanged">
          <Binding.ValidationRules>
            <ExceptionValidationRule/>
          </Binding.ValidationRules>
        </Binding>
      </TextBox.Text>
    </TextBox>

在后台代碼中:

 
        BindingExpression myBindingExpression = textBox3.GetBindingExpression(TextBox.TextProperty);
            Binding myBinding = myBindingExpression.ParentBinding;
            myBinding.UpdateSourceExceptionFilter = new UpdateSourceExceptionFilterCallback(ReturnExceptionHandler);
            myBindingExpression.UpdateSource();
 

因為Age3Int類型,在textBox3 輸入非int類型,將會引發異常,此時使用Rule的正是系統的ExceptionValidationRule,同樣錯誤信息的模塊不變.

  • 驗證所有控件

    在點擊確定可使用該方法再次驗證,在數據不合法的情況下,使用戶無法提交

代碼: 下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM