开发者

data validation using IDataErrorInfo and MVVM Pattern problem

I'm having a WEIRD problem when data validating using IDataErrorInfo on a WPF MVVM application, what I'm doing is :

the property to be validated

public Decimal GlassPrice
    {
        get
        {
            return _GlassPrice;
        }
        set
        {
            if (_GlassPrice != value)
            {
                _GlassPrice = value;
                OnPropertyChanged("GlassPrice");
                CarName = allPropertiesValid.ToString();
            }
        }
    }

"I will explain the last line in the above "Set" function CarName = .. etc later" then, a bool variable with default value of false to represent if all the properties to be validated are true, used in canExecute function.

public bool allPropertiesValid
    {

        get { return _allPropertiesValid; }
        set
        {
            if (_allPropertiesValid != value)
            {
                _allPropertiesValid = value;
                OnPropertyChanged("allPropertiesValid");
            }
        }
    }

then a dictionary to hold the pairs of property names with a bool value,as follows

 validAllProperties = new Dictionary<string, bool>();
 validAllProperties.Add("GlassPrice", false);

then, of course a method to validate the property as follows

private string validateGlassPrice()
    {
        if (GlassPrice <= 0)
        {
            return "price can't be 0 nor a minus value ";
        }
        else
        {
            return String.Empty;
        }   
    }

then on the IDataErrorInfo implementation

string IDataErrorInfo.this[string columnName]
    {
        get
        {
            string error = String.Empty;
            switch (columnName)
            {
                case "GlassPrice":
                error = validateGlassPrice();
                validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error) ? true : false;
                validateAllProperties();
                return error;
                default:
                throw new ApplicationException("Wrong Property name being validated");
            }

        }
    }

lastly a method to set the final value of "allPropertiesValid" depends on the bool values in the dictionary

private void validateAllProperties()
    {
        foreach (bool isValid in validAllProperties.Values)
        {
            if (isValid == false)
            {
                allPropertiesValid = false;
                return;
            }
        }
        allPropertiesValid = true;
    }

the CarName I said I will explain later is a property bound to a textBox, and I used it now to track the "allPropertiesValid" value on the runtime, so I make the canExecute Method return "allPropertiesValid" and depend on that the button asociated with the command will be enabled/disabled, this scenario is just working fine , I've done 3 or 4 forms using it and they work perfectly,however in this particular one it doesn't, after revisioning, it turns out that the problem is only on this particular property "GlassPrice", I disabled all the validation on other properties and just kept it on this , what happen now is : when entering 1 as a value the Carname give me false but the button is now enabled ?? the button should never be enabled as long as the value on CanExecute method is false, then I add zero to 1 and they become 10 then it turns to True, and remains as True regardless of values change in the textBox, even if I entered a not-valid data like 0 or null it remains true and the button is always enabled ?? I sat for hours trying to solve this, I hope someone can help me out

Thanks in advance

Edit: Well now the problem is:how to check a D开发者_如何学Cecimal when the TextBox is blank ??,GlassPrice is Decimal and the Decimal won't accept null values, the following method checks GlassPrice against if it is 0 or minus , but not null or blank

private string validateGlassPrice()
    {
        if (GlassPrice <= 0)
        {
            return "price can't be 0 nor a minus value ";
        }
        else
        {
            return String.Empty;
        }   
    }


I can't see anything obviously wrong in what you've posted. Here are a couple of suggestions that may help you find the problem:

First, the behavior you want to see (a button being enabled/disabled) is dependent on CanExecute being evaluated and returning the right value. Is this actually happening? A good way to find out is to write messages to the console in the CanExecute method, e.g.:

Console.WriteLine("CanExecute called; returning " + result);
return result;

You can then keep the Output window on the screen while you're using your program and see if the property is being evaluated when you expect it to be, and if, at the time that it's being evaluated, it's returning the value you expect it to.

A second suggestion is that you start using string constants instead of literals in your view model. I don't see that you've made any mistake here, but the code you've posted uses the string literal "GlassPrice" in three different places. If any of those is misspelled, your code will fail in a way you're not expecting.

Finally, two stylistic issues - these aren't the source of your problem, but they'll simplify your code. This:

validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error) ? true : false;

should be this:

validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error);

and this:

foreach (bool isValid in validAllProperties.Values)
{
    if (isValid == false)
    {
        allPropertiesValid = false;
        return;
    }
}
allPropertiesValid = true;

can just as easily be this:

allPropertiesValid = validAllProperties.Values.All(x => x);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜