1. 程式人生 > >WPF中的數據驗證

WPF中的數據驗證

info 數據源 upd null als 其中 eve 數據流 分享圖片

WPF的Binding使得數據能夠在數據源和目標之間流通,在數據流通的中間,便能夠對數據做一些處理。
數據轉換數據驗證便是在數據從源到目標 or 從目標到源 的時候對數據的驗證和轉換。
技術分享圖片

ValidationRule 驗證規則

WPF中提供了一個抽象類ValidationRule,我們自定義的驗證規則都需要繼承它,然後實現它的抽象
方法Validate,該方法需要返回一個ValidationResult對象來表示驗證結果。舉個例子,一個驗證數字
的規則(輸入的只能是數字)

public class NumberValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if (Regex.IsMatch(value.ToString(), "^[0-9]+$"))
            {
                return new ValidationResult(true, null);
            }
            else
            {
                return new ValidationResult(false, "請輸入數字");
            }
        }
    }

其中ValidationRule的兩個屬性

  • ValidatesOnTargetUpdated

    該屬性可以確定驗證的方向,如果設置為false,那麽只驗證從目標到源的方向,如果為True,
    那麽同時也會驗證從源到目標的方向

  • ValidationStep
    該屬性確定了驗證的時機,它是一個枚舉值
    1 CommittedValue,該值提交到數據源後,運行ValidationRule,即不管驗證是否能通過,屬性都會被更新
    2 ConvertedProposedValue,在進行了轉換之後,運行ValidationRule,如果有數據轉換,那麽先轉換再驗證
    3 RawProposedValue,在任何轉換發生之前,運行ValidationRule
    4 UpdatedValue,在更新了源後,運行ValidationRule,即屬性值被更改之後,就會去驗證,註意需要
    ValidatesOnTargetUpdated

    設置為True

還需要註意的是Binding對驗證結果的處理,NotifyOnValidationError設置為True,即當發生驗證
錯誤時,錯誤信息會從目標沿著可視樹往上冒泡,直到該冒泡事件被偵聽到並被處理。

   <TextBox Grid.Row="1">
            <TextBox.Text>
                <Binding Path="Number" UpdateSourceTrigger="PropertyChanged" Converter="{StaticResource Converter}" NotifyOnValidationError="True">
                    <Binding.ValidationRules>
                        <validationRules:NumberValidationRule ValidatesOnTargetUpdated="True" ValidationStep="CommittedValue"></validationRules:NumberValidationRule>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

當出現驗證錯誤時,TextBox就會有一個紅色的框,這是默認的錯誤模板樣式,我們如何定義一個錯誤模板(ErrorTemplate)呢

錯誤模板 ErrorTemplate

   <ControlTemplate x:Key="ErrorTemplate">
            <StackPanel Orientation="Horizontal">
                <AdornedElementPlaceholder x:Name="Placeholder"></AdornedElementPlaceholder>
                <TextBlock Foreground="Red" Text="{Binding ElementName=Placeholder,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" FontSize="20" x:Name="txt"></TextBlock>
            </StackPanel>
        </ControlTemplate>
  <TextBox Grid.Row="1" Height="30" Width="100" Validation.ErrorTemplate="{StaticResource ErrorTemplate}">

AdornedElementPlaceholder表示一個占位符,這裏表示具體的控件即TextBox,這裏表示錯誤模板的布局是
如果有驗證錯誤,那麽在TextBox的後邊會有一個TextBlock文本,文本的內容顯示的是驗證錯誤的信息。

Validation

這裏涉及到了一個類Validation,它是一個靜態類,它的使用大多以附加屬性出現。它的主要功能是
1 設置ErrorTemplate
2 判斷是否有錯誤(HasError),以及獲取錯誤列表(Errors)
3 偵聽驗證錯誤事件

前兩點前面都有提到,現在來看下 偵聽驗證錯誤冒泡事件

<Grid Grid.Row="1" Validation.Error="Validation_OnError">
            <TextBox Height="30" Width="100" Validation.ErrorTemplate="{StaticResource ErrorTemplate}">
                <TextBox.Text>
                    <Binding Path="Number" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
                        <Binding.ValidationRules>
                            <validationRules:NumberValidationRule></validationRules:NumberValidationRule>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
        </Grid>

 private void Validation_OnError(object sender, ValidationErrorEventArgs e)
    {

        if (e.Action == ValidationErrorEventAction.Added)
        {
            //todo:新的驗證錯誤
            _errorMessage = e.Error.ErrorContent.ToString();
        }
        else
        {
            //todo:清除原有錯誤
            _errorMessage = string.Empty;
        }
    }

這裏需要註意的其實就是ValidationErrorEventAction這個枚舉值,因為產生新的驗證錯誤,和清除
原來的驗證錯誤都會觸發這個事件,所以需要區分開來對待。
至此,WPF中的數據驗證差不多了。

WPF中的數據驗證