WPF中的數據驗證
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
還需要註意的是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中的數據驗證