WPF ValidationRule и проверка.Ошибка не вызывает событие

#wpf

#wpf

Вопрос:

Что не так с этим кодом, проверка.Ошибка никогда не вызывается, тогда как я установил для свойства NotifyOnValidationError и NotifyOnValidationError значение True, а также для него. Итак, метод «Grid_Error(отправитель объекта, ValidationErrorEventArgs e)» никогда не выполняется, но я не знаю почему : (

 <Window xmlns:my="clr-namespace:WpfDigitalClock;assembly=WpfDigitalClock"  x:Class="WpfApplication1.MainWindow"
    xmlns:local="clr-namespace:WpfApplication1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:Names x:Key="MyNames" />
</Window.Resources>
<Grid Validation.Error="Grid_Error">
    <TextBox Height="21" Margin="12,62,0,0" Name="TextBox1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120">
        <TextBox.Text>
            <Binding Source="{StaticResource MyNames}" Path="FirstName" NotifyOnValidationError="True">
                <Binding.ValidationRules>
                    <local:StringValidator />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <TextBox Height="21" HorizontalAlignment="Right" Margin="0,62,12,0" Name="TextBox2" VerticalAlignment="Top" Width="120" >
        <TextBox.Text>
            <Binding Source="{StaticResource MyNames}" Path="LastName" NotifyOnValidationError="True">
                <Binding.ValidationRules>
                    <local:StringValidator />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <Button HorizontalAlignment="Left" Margin="35,122,0,116" Name="Button1" Width="75" Click="Button1_Click">Back</Button>
    <Button HorizontalAlignment="Right" Margin="0,122,34,117" Name="Button2" Width="75" Click="Button2_Click">Forward</Button>
    <Button Height="22" Margin="101,0,101,56" Name="Button3" VerticalAlignment="Bottom" Click="Button3_Click">Add</Button>
</Grid>
  

в файле Window1.xaml.cs :

 public class StringValidator : ValidationRule
{
    public override ValidationResult Validate(object value,
       System.Globalization.CultureInfo cultureinfo)
    {
        string aString = value.ToString();
        if (aString == "")
            return new ValidationResult(false, "String cannot be null");
        return new ValidationResult(true, null);
    }
}

private void Grid_Error(object sender, ValidationErrorEventArgs e)
{
    if(e.Action == ValidationErrorEventAction.Added) 
        MessageBox.Show(e.Error.ErrorContent.ToString());
}
  

Спасибо за вашу помощь!

Редактировать :

Здесь мои имена Class :

 class Names : ObservableCollection<Name>
{
    public Names ()
    {
        Name aName = new Name("FirstName "   (this.Count  1).ToString(),
            "LastName "   (this.Count   1).ToString());

        this.Add(aName);
    }
}
  

Здесь мое имя class :

 class Name : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _firstName;
    private string _lastName;


    public Name(string fName,  string lName)
    {
        _firstName = fName;
        _lastName = lName;
    }

    public string FirstName 
    { 
        get
        {
            return _firstName;
        }
        set
        {
            _firstName = value; 
            PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
        }
    }
    public string LastName 
    {
        get
        {
            return _lastName;
        }
        set
        {
            _lastName = value; 
            PropertyChanged(this, new PropertyChangedEventArgs("LastName"));
        }
    }
}
  

Комментарии:

1. Отображаются ли текстовые поля с ошибкой (по умолчанию красная рамка)?

2. как вы в конечном итоге это исправили?

Ответ №1:

Приложение не может изменить содержимое этой коллекции. Смотрите раздел Example для примера того, как использовать это прикрепленное свойство.

Модель привязки данных WPF позволяет связать ValidationRules с вашим объектом привязки. Проверка происходит во время передачи значения цели привязки к источнику привязки перед вызовом преобразователя. Ниже описывается процесс проверки:

1. Когда значение передается из целевого свойства в исходное свойство, механизм привязки данных сначала удаляет любую ошибку ValidationError, которая могла быть добавлена к проверке.Ошибка прикрепленного свойства связанного элемента. Затем он проверяет, есть ли какие-либо пользовательские ValidationRules, определенные для этой привязки, и в этом случае он вызывает метод Validate для каждого из ValidationRules, пока одно из них не столкнется с ошибкой или пока все они не пройдут.

2. Как только есть пользовательское правило, которое не проходит, механизм привязки создает объект ValidationError и добавляет его к проверке.Ошибки при сборе связанного элемента. При проверке.Ошибка не пуста, проверка.Для свойства элемента, прикрепленного к hasError, установлено значение true. Кроме того, если для свойства NotifyOnValidationError привязки установлено значение true, то механизм привязки запускает проверку.Ошибка, связанная с событием в элементе.

3. Если все правила выполняются, механизм привязки затем вызывает конвертер, если таковой существует.

4. Если преобразователь проходит, механизм привязки вызывает параметр исходного свойства.

5. Если с привязкой связано ExceptionValidationRule и на шаге 4 генерируется исключение, механизм привязки проверяет, существует ли UpdateSourceExceptionФильтр. У вас есть возможность использовать обратный вызов UpdateSourceExceptionFilter, чтобы предоставить пользовательский обработчик для обработки исключений. Если в привязке не указан UpdateSourceExceptionFilter, механизм привязки создает ValidationError с исключением и добавляет его к проверке.Ошибки при сборе связанного элемента.

Также обратите внимание, что передача допустимого значения в любом направлении (от целевого к исходному или от источника к целевому) завершает проверку.Ошибка прикрепленного свойства.

Для получения информации о поведении этого свойства в сценариях с несколькими привязками см. ValidationError.

Ответ №2:

Из вашего комментария я бы сделал вывод, что ValidationRule не возвращает ошибку, следовательно, событие error не запускается. Попробуйте пошагово выполнить метод проверки с помощью отладчика.

Кроме того, проверка выполняется только при обновлении исходного кода в текстовых полях, которые обычно выполняются на LostFocus .

Редактировать: MyNames это коллекция, у нее нет свойств, к которым вы пытаетесь привязаться, в окне вывода должны быть ошибки привязки.

Если вы хотите выполнить привязку к первому элементу, вам нужно изменить путь на что-то вроде [0].LastName для привязки по фамилии.

Комментарии:

1. Когда я вставляю точку останова в метод Validate моего класса StringValidator, точка останова никогда не достигается.

2. Проверка выполняется только при обновлении исходного кода в текстовых полях, которые обычно выполняются на LostFocus . Вы отредактировали текстовое поле и щелкнули где-нибудь еще?

3. Да, я заполняю . Текстовое свойство 2 текстовых полей с именами «TextBox1» и «TextBox2», затем я нажимаю на кнопку с именем «Button3»

4. На самом деле вы правы! Должен быть вызван LostFocus!!! В противном случае проверка не вызывается.

5. По-видимому, TextChanged также должен быть вызван

Ответ №3:

Реализует ли ваш класс Names INotifyPropertyChanged?

В коде, лежащем в основе файла, установите datacontext в this . Предоставьте свой Names объект как свойство там и посмотрите, работает ли это. Мне не нравится привязка к статическому ресурсу в окне.