在我們給控件的某個屬性賦值或者當控件的某個屬性值改變時,我們可能會需要檢查這個值是不是在規定的範圍內。如果這個值不在規定的範圍內,我們需要給出提示。WPF中實現這個功能的類是ValidationRule。先看一個例子吧:
xaml代碼:
<Window x:Class="BindValidationRule.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindValidationRule"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBox x:Name="textBox1" Margin="5"/>
<Slider x:Name="slider1" Minimum="-100" Maximum="200" Margin="5"/>
</StackPanel>
</Window>
c#代碼:
public MainWindow()
{
InitializeComponent();
Binding binding = new Binding("Value") { Source = slider1 };
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.NotifyOnValidationError = true;
RangeValidationRule rangeValidationRule = new RangeValidationRule();
binding.ValidationRules.Add(rangeValidationRule);
rangeValidationRule.ValidatesOnTargetUpdated = true;
textBox1.SetBinding(TextBox.TextProperty, binding);
textBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(ValidationError));
}
void ValidationError(object sender,RoutedEventArgs e)
{
if(Validation.GetErrors(textBox1).Count>0)
{
var errMessage = (e as ValidationErrorEventArgs).Error.ErrorContent.ToString();
textBox1.ToolTip = errMessage;
}
}
校驗規則類:
public class RangeValidationRule:ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if(double.TryParse(value.ToString(), out double d))
{
if(d>=0 && d<=100)
{
return new ValidationResult(true, null);
}
}
return new ValidationResult(false, "Validation Range Failed");
}
}
大家對ValidationRule轉到定義可以看到,這個一個抽象類,Validate是一個抽象方法,必須由它的子類實現檢驗的規則,由它的子類來決定什麼樣的數據是合法的,什麼是不合法的。我們這裏定義了類繼承自ValidationRule,並實現了抽象方法。
Validate方法的目標控件是slider1,它規定slider1的值在0-100之間是合法的,否則就是不合法的。
那Binding是如何和ValidationRule關聯起來的呢?binding.ValidationRules.Add(rangeValidationRule);這條語句實現了他們之間的關聯,從這條語句可以看出,一個Binding可以設置多個校驗規則。
rangeValidationRule.ValidatesOnTargetUpdated = true;這條語句的的作用是當目標控件的屬性值(binding指定)改變時,rangeValidationRule就會執行Validate方法進行校驗。如果把屬性值設置爲false,則rangeValidationRule不會校驗。
binding.NotifyOnValidationError = true;這個語句的作用是當rangeValidationRule檢驗數據不合法時,是不是要通知binding。
當binding接收到數據不合法時,就會調用textBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(ValidationError))這條語句指定數據不合法的處理函數。如果binding.NotifyOnValidationError = false則ValidationError函數不會執行。
我們再來看看數據檢驗失敗時指定的處理函數ValidationError。當數據檢驗失敗時我們返回了"Validation Range Failed"這個字符串類型的錯誤信息。那麼我們把RoutedEventArgs通過多態轉換成ValidationErrorEventArgs,因爲後者是繼承自前者,所以這裏的轉換是成功的。ToolTip這個屬性的作用是:當我們把鼠標移動到這個文本框時,會在鼠標旁邊顯示錯誤信息,如圖: