简体   繁体   中英

Silverlight DataGrid column validation

I have a datagrid in my application and i need certain column of datagrid to have sum of values equal to 100.

As in:

a 20

b 20

c 60

this one is right

a 20

b 20

c 62

this one is not right

Is there any ideas how i can implement this with MVVM ad INotifyDataErrorInfo?

My problem now is that if i just bind properties to the cell and then throw ErrorChanged, datagrid will lock me on the row i have changed data in, so i won't be able to move anywhere unless i restore original value so that sum in the column would become 100 again.

Please do not post various codebehind solutions with manual validations on CellEdit or anything like this - I can write such dirty code myself. I'm trying to find clean solution that fits with binding and MVVM

As far as I see it though Silverlight datagrid is just utterly broken, unfinished and nobody cares. Maybe someone knows of proper datagrid out there.(Or maybe they actually fixed it in Silverlight 5?)

For now following used:

In my ViewModel constructor

        validator = new Validator(this);
        validator.AddValidationFor(() => PayElements).When(() => _payElements.Where(p1 => (!String.IsNullOrEmpty(p1.Distribution) && FormatChecker.IsDecimal(p1.Distribution, 3, 2))).Sum(p2 => Decimal.Parse(p2.Distribution)) != 100).Show("ERROR!");

where PayElements is my collection(btw, my bad, it is actually ICollectionView created from _payElements, which is ObservableCollection). Then OnChanges to any object

        validator.ValidateAll();

which causes validation rule created in constructor to be evaluated. After this I have Error in my viewmodel's errorCOllection for the whole object collection, but it does not show any red borders. well at list i can see that there is an error and disable save button :)

I have implemented nasty validation on the datagrid and unless you have to perform async validation it is pretty well done from the binded object. I am not sure about the objects you are binding to the list but I would use something like the following:

public string Col1Wrapper
{
    get
    {
        return this.Col1;
    }
    set
    {
        ValidateRequired("Col1Wrapper", value, "Required");
        ValidateRegularExpression("Col1Wrapper", value, @"^[\d]+$", "Must be digit");
        ValidateTotal(value,Col2,Col3,total);//in your case
        this.Col1 = value;
        this.RaisePropertyChanged("Col1Wrapper");
    }
}

public string Col2Wrapper
{
    get
    {
        return this.Col2;
    }
    set
    {
        ValidateRequired("Col2Wrapper", value, "Required");
        ValidateRegularExpression("Col2Wrapper", value, @"^[\d]+$", "Must be digit");
        ValidateTotal(Col1,value,Col3,total);//in your case
        this.Col2 = value;
        this.RaisePropertyChanged("Col2Wrapper");
    }
}

public string Col3Wrapper
{
    get
    {
        return this.Col3;
    }
    set
    {
        ValidateRequired("Col3Wrapper", value, "Required");
        ValidateRegularExpression("Col3Wrapper", value, @"^[\d]+$", "Must be digit");
        ValidateTotal(Col1,Col2,value,total);//in your case
        this.Col3 = value;
        this.RaisePropertyChanged("Col3Wrapper");
    }
}

Then using the http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo%28VS.95%29.aspx

default implementation is in the example section.

public bool ValidateRequired(string property, string value, string errorMessage)
{
    bool isValid = true;

    if (value == null || value == string.Empty)
    {
        AddError(property, errorMessage, false);
        isValid = false;
    }
    else RemoveError(property, errorMessage);
    RaiseErrorsChanged(property);
    return isValid;
}

public bool ValidateRegularExpression(string property, string value, string expression, string errorMessage)
{
    ...
}

public bool ValidateTotal(string property,int 1, int 2, int 3, int total, string errorMessage)
{
    if((1+2+3) != total)
        AddError(property, errorMessage, false);
    else RemoveError(property, errorMessage);
}

The add error method will trigger the validation summary to be displayed on the datagrid. Hope this is what you were looking for.

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