WPF學習筆記:Binding對數據的校驗

在我們給控件的某個屬性賦值或者當控件的某個屬性值改變時,我們可能會需要檢查這個值是不是在規定的範圍內。如果這個值不在規定的範圍內,我們需要給出提示。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這個屬性的作用是:當我們把鼠標移動到這個文本框時,會在鼠標旁邊顯示錯誤信息,如圖:

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章