當填寫表單時,需要對填寫的內容進行驗證,檢查數據是否符合要求,比如字符串的長度、日期的格式、數字等。WPF支持自定義驗證規則,並提供可視化反饋,以便在輸入無效值時向用戶發出通知。
下面的示例將演示一個模擬員工信息錄入的過程,如果年齡不再給定的輸入範圍內,將在文本框的後面顯示一個紅色的歎號,當鼠標移至錯誤文本框時,顯示提示消息,提示用戶正確的輸入格式。
主要內容爲:自定義驗證規則、定義輸入錯誤時控件的外觀、定義樣式觸發器顯示錯誤提示
自定義驗證規則
可以繼承ValidationRule類,重寫Validate方法,實現自定義的驗證規則
下面是年齡的驗證規則的實現:
public class AgeRangeRule : ValidationRule
{
private int _min;
private int _max;
public AgeRangeRule()
{
}
public int Min
{
get { return _min; }
set { _min = value; }
}
public int Max
{
get { return _max; }
set { _max = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
int age = 0;
try
{
if (((string)value).Length > 0)
age = Int32.Parse((String)value);
}
catch (Exception e)
{
return new ValidationResult(false, "輸入的數字無效!");
}
if ((age < Min) || (age > Max))
{
return new ValidationResult(false,
"輸入的年齡範圍必須在: " + Min + " - " + Max + "之間");
}
else
{
return new ValidationResult(true, null);
}
}
}
其中ValidationRule的兩個屬性
ValidatesOnTargetUpdated
該屬性可以確定驗證的方向,如果設置爲false,那麼只驗證從目標到源的方向,如果爲True,
那麼同時也會驗證從源到目標的方向
ValidationStep
該屬性確定了驗證的時機,它是一個枚舉值
1 CommittedValue,該值提交到數據源後,運行ValidationRule,即不管驗證是否能通過,屬性都會被更新
2 ConvertedProposedValue,在進行了轉換之後,運行ValidationRule,如果有數據轉換,那麼先轉換再驗證
3 RawProposedValue,在任何轉換髮生之前,運行ValidationRule
4 UpdatedValue,在更新了源後,運行ValidationRule,即屬性值被更改之後,就會去驗證,注意需要
ValidatesOnTargetUpdated設置爲True
還需要注意的是Binding對驗證結果的處理,NotifyOnValidationError設置爲True,即當發生驗證
錯誤時,錯誤信息會從目標沿着可視樹往上冒泡,直到該冒泡事件被偵聽到並被處理。
定義輸入錯誤時控件的外觀
自定義的 ControlTemplate,它用於創建一個紅色感嘆號,以通知用戶驗證錯誤。 控件模板用於重新定義控件的外觀。
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<AdornedElementPlaceholder/>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
</DockPanel>
</ControlTemplate>
AdornedElementPlaceholder表示一個佔位符,這裏表示具體的控件即TextBox,這裏表示錯誤模板的佈局是
如果有驗證錯誤,那麼在TextBox的後邊會有一個TextBlock文本,文本的內容顯示的是驗證錯誤的信息。
定義樣式觸發器顯示錯誤提示
顯示錯誤消息的 ToolTip 是使用名爲 textBoxInError 的樣式創建的。 如果 HasError 的值是 true,則觸發器將當前 TextBox 的工具提示設置爲其第一個驗證錯誤。 RelativeSource 設置爲 Self,以引用當前元素。
<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>
控件綁定相應的模板和樣式
<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 employee}"
UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<c:AgeRangeRule Min="21" Max="130"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Validation
這裏涉及到了一個類Validation
,它是一個靜態類,它的使用大多以附加屬性出現。它的主要功能是
1 設置ErrorTemplate
2 判斷是否有錯誤(HasError),以及獲取錯誤列表(Errors)
3 偵聽驗證錯誤事件
前兩點前面都有提到,現在來看下 偵聽驗證錯誤冒泡事件
當輸入的年齡不在定義範圍內時,控件的顯示方式如下:
注:當數據綁定驗證時,如果驗證規則的ValidationStep屬性設置爲RawProposedValue或ConvertedProposedValue值時,在驗證失敗的情況下,數據不會更新到源,這也在情理之中,不合格的數據我們當然不接受。