IDataErrorInfo: проверка при отправке страницы - PullRequest
4 голосов
/ 07 апреля 2010

Я создаю приложение WPF, которое будет использовать IDataErrorInfo проверку данных, которую реализуют мои бизнес-объекты.Я работал с этой демонстрацией из поста в блоге , чтобы понять ValidatesOnDataErrors.

Эта демонстрация - тривиальное приложение, которое связывает пару текстовых полей с объектом Contact и реализует IDataErrorInfo проверка, используя ValidatesOnDataErrors=True в привязке данных.Чтобы быть действительным, текстовое поле должно содержать не менее пяти символов.

Вот моя проблема: в демоверсии проверка запускается всякий раз, когда текстовое поле теряет фокус.Фактически, текстовые поля инициализируются в недопустимое состояние (красные границы) при запуске приложения.Мое приложение должно отложить проверку, пока пользователь не нажмет кнопку ОК, чтобы отправить страницу.В это время текстовые поля должны быть проверены и переведены в состояние ошибки, если они недействительны.

Итак, как мне отложить проверку текстовых полей до тех пор, пока пользователь не нажмет кнопку ОК?Спасибо за вашу помощь.

Ответы [ 2 ]

7 голосов
/ 07 апреля 2010

Спасибо Михаилу за помощь. К сожалению, мне нужно, чтобы привязки оставались постоянно синхронизированными, с отложенной проверкой. В противном случае решение Майкла сделало бы эту работу. Итак, я пошел в несколько ином направлении. Вот решение, которое я в конечном итоге реализовал.

Простая демонстрация: Начнем с самого простого случая: мои бизнес-объекты реализуют IDataErrorInfo; давайте предположим, что я могу изменить, как это реализовано. Я даю каждому бизнес-объекту дополнительное логическое свойство ValidationEnabled и изменяю реализацию IDataErrorInfo, чтобы всегда возвращать нулевой результат, если это свойство имеет значение false.

В демонстрации, о которой я упоминал в своем первоначальном посте, используется объект Contact с двумя свойствами; Имя и фамилия. Я добавил свойство ValidationEnabled и изменил реализацию IDataErrorInfo следующим образом:

#region IDataErrorInfo Members

public string Error
{
    get { throw new System.NotImplementedException(); }
}

public string this[string columnName]
{
    get 
    {
        // Initialize
        string result = null;

        // Perform validation only if enabled
        if (ValidationEnabled)
        {
            switch (columnName)
            {
                // Validate 'First Name' 
                case "FirstName":
                    if (string.IsNullOrEmpty(FirstName))
                    {
                        result = "First name has to be set";
                    }
                    else if(FirstName.Length < 5)
                    {
                        result = "First name must be at least five characters";
                    }
                    break;

                // Validate "Last Name"
                case "LastName":
                    if (string.IsNullOrEmpty(LastName))
                    {
                        result = "Last name has to be set";
                    }
                    else if (LastName.Length < 5)
                    {
                        result = "Last name must be at least five characters";
                    }
                    break;
            }
        }

        // Set return value
        return result;
    }
}

#endregion

В моей версии простой демонстрации я подключаю кнопку «Отправить» к обработчику событий в коде, который включает проверку и обновляет привязки для обоих текстовых полей:

private void OnButtonClick(object sender, RoutedEventArgs e)
{
    var contact = (Contact) DataContext;
    contact.ValidationEnabled = true;
    var binding = FirstNameBox.GetBindingExpression(TextBox.TextProperty);
    binding.UpdateSource();
    binding = LastNameBox.GetBindingExpression(TextBox.TextProperty);
    binding.UpdateSource();
}

Теперь красные контуры не отображаются, пока я не попытаюсь отправить форму.

Реальный мир: В моем производственном приложении я не управляю бизнес-объектами и не могу изменять их, как в своей простой демонстрации. Итак, я создаю простую сквозную оболочку для бизнес-объекта, которая предоставляет свойства для привязки к представлению и связывает эти свойства с соответствующими свойствами обернутого бизнес-объекта. Оболочка реализует IDataErrorInfo и содержит свойство ValidationEnabled.

Реализация оболочки IDataErrorInfo всегда возвращает ноль, если проверка не включена. Если проверка включена, то оболочка вызывает реализацию IDataErrorInfo для обернутого объекта и возвращает то, что получает оттуда.

Этот подход будет знаком всем, кто использует шаблон Model-View-ViewModel. То, что мы делаем, - это создание оболочки бизнес-объекта для модели представления, что многими разработчиками считается лучшей практикой MVVM. Он отделяет задачу UI (подавляя красные границы до отправки страницы) от задачи бизнес-модели (простая проверка объектов).

Кроме того, мое производственное приложение не будет использовать обработчики событий в программном коде. Для MVVM кнопка будет подключена к ICommand, который будет содержать логику из обработчика OnButtonClick () в простой демонстрационной версии.

Надеюсь, это пригодится всем, кто исследует эту проблему в будущем.

0 голосов
/ 07 апреля 2010

Привязка данных имеет свойство UpdateSourceTrigger. Как следует из названия, оно указывает, когда обновлять источник привязки. Для свойства Text по умолчанию установлено значение LostFocus. Вы можете установить для него значение Explicit и вызвать метод UpdateSource выражения BindingExpression в коде. С другой стороны, вы также можете отложить создание события PropertyChanged. Однако, я думаю, это не решит проблему проверки при запуске приложения. Надеюсь, это поможет как-то.

...