WPF/Caliburn.Micro — проверка ввода с использованием IDataErrorInfo

У меня есть следующий код в моем приложении WPF, и я пытаюсь реализовать проверку ввода.

Модель:

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

ViewModel:

public class CustomerViewModel : Screen, IDataErrorInfo
{
    private Customer _customer;
    public Customer Customer
    {
        get { return _customer; }
        set
        {
            if (_customer != value)
            {
                _customer = value;
                NotifyOfPropertyChange(() => Customer);
            }
        }
    }

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

    public string this[string columnName]
    {
        get
        {
            string result = null;
            if (columnName == "Name")
            {
                if (string.IsNullOrEmpty(Customer.Name))
                    result = "Please enter a Name";
                if (Customer.Name.Length < 3)
                    result = "Name is too short";
            }
            return result;
        }
    }
}

Вид:

<TextBox Text="{Binding Customer.Name, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=true, NotifyOnValidationError=true}"/>

Проблема. Решение не работает должным образом. Ничего не происходит при вводе данных в текстовое поле. Я не уверен, что сделал правильные шаги.

Может ли кто-нибудь мне помочь?


person Rahul    schedule 04.11.2015    source источник
comment
Как насчет того, чтобы попробовать UpdateSourceTrigger=PropertyChanged?   -  person Mike Eason    schedule 04.11.2015


Ответы (1)


Я предполагаю, что проблема возникает из-за того, что в вашей модели представления нет свойства Name (но внутри класса Customer). Ваша работа с вложенным свойством в вашей привязке Customer.Name.

Я не использовал это в сочетании с проверкой IDataErrorInfo.

В настоящее время это условие внутри индексатора модели просмотра не будет выполнено:

if (columnName == "Name")
{
...
}

потому что индексатор никогда не вызывается.


Мое предложение

Добавьте в модель представления свойство Name, которое будет представлять имя клиента. Затем вы можете инициализировать свою модель представления с помощью класса клиента, например настройки

Name = customer.Name

в конструкторе моделей представлений.

Ваша привязка должна измениться на

<TextBox Text="{Binding Name  ....

После этого индексатор должен заработать, потому что теперь в вашей модели представления есть свойство Name.

Возможно, есть другое решение, которое позволит вам сохранить текущую вложенную привязку (Customer.Name), но я этого точно не знаю.

person Martin    schedule 04.11.2015
comment
Почти уверен, что это именно та ситуация, поскольку у Заказчика нет унаследованных INotifyDataErrorInfo/IDataErrorInfo, обработка ошибок не всплывает. Если вы идете по маршруту модели поверх маршрута модели представления, ожидайте вдвое больше кода. Соглашение, встроенное в ConventionManager, явно ищет интерфейс(ы) INotifyDataErrorInfo/IDataErrorInfo и связывает ValidatesOnError и NotifyOnValidationErrors со значением true. Проще выполнить проверку со свойствами в модели представления, а затем присвоить результаты рассматриваемому объекту. - person mvermef; 04.11.2015