简体   繁体   中英

WPF/Caliburn.Micro - Input Validation using IDataErrorInfo

I have following code in my WPF application and I'm trying to implement input validation.

Model:

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;
        }
    }
}

View:

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

Problem: The solution is not working as expected. Nothing happens when type data in Textbox. I'm not sure weather I have followed the right steps.

Could any one help me?

I presume the problem occurs because there is no Name property in your view model (but inside the Customer class). Your work with a nested property in your binding Customer.Name .

I have not used this in combination with IDataErrorInfo validation.

Currently this condition inside you view model indexer will not be hit:

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

because the indexer is never called.


My suggestion

Add a Name property to your view model which will represent the customers name. You can then initialize your view model with the customer class like setting

Name = customer.Name

in the view models constructor.

Your binding would need to change to

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

After doing this, the indexer should be working, because now there is a Name property in your view model.

Perhaps there is another solution which would let you keep you current nested binding ( Customer.Name ), but I do not know this for sure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM