Home > Enterprise >  How to read current edited value during Row Validation Rule WPF datagrid
How to read current edited value during Row Validation Rule WPF datagrid

Time:12-15

I have this Validation Rule:

 public override ValidationResult Validate(object value, CultureInfo cultureInfo) {

        DteqModel Dteq = (value as BindingGroup).Items[0] as DteqModel;

        if (CheckCircularReference(Dteq, Dteq.FedFrom)) {
            return new ValidationResult(false, "Equipment cannot be fed from itself");
        }

        return new ValidationResult(true, null);
    }

This is applied as a RowValidaiton on a DataGrid and it's working but not 100% as expected. Dteq.FedFrom is a combobox, and the the validation acts on the previous value in the row/cells, not the values I currently entered after RowEndEdit. It appears the validation is done before the values are saved to the actual collection object. I am using NotifyProperty changed on all objects and the collection in the datagrid is an observable collection.

DteqModel Dteq = (value as BindingGroup).Items[0] 

How do I get the above line to read the data as it is currently in the row? Right now if I enter an invalid result, I have to enter edit mode twice for the failed validation to take effect. And after that, I can't change it back to anything valid because it always results in a failed validation and won't update the value.

For reference CheckCircularReference just checks to see if Dteq.Tag == Dteq.FedFrom, either directly or through the full tree of parent/child relationship.

private bool CheckCircularReference(DteqModel startDteq, string nextDteq, int counter =1) {
        var dteqDict = Dictionaries.dteqDict;
        if (nextDteq == "" & counter == 1) { // sets the initial FedFrom
            nextDteq = startDteq.FedFrom;
        }

        if (dteqDict.ContainsKey(nextDteq) == false || nextDteq == "" || counter > dteqDict.Count) { // all equipment has been checked
            return false;
        }
        else if (startDteq.FedFrom == startDteq.Tag) { // if the equipment is fed from itself
            return true;
        }
        else if (dteqDict.ContainsKey(nextDteq)) {
            if (dteqDict[nextDteq].FedFrom == startDteq.Tag) { // if the equipment is indirectly fed from itself
                return true;
            }
            counter  = 1;
            return CheckCircularReference(startDteq, dteqDict[nextDteq].FedFrom, counter); // if not increase the count and check the next Equipment
        }
        
        return false;
    }

Thanks in advance.

CodePudding user response:

I had to add validation step to my XAML.

XAML with erroneous behavior:

<DataGrid.RowValidationRules>
    <rules:InvalidFedFromRule ValidatesOnTargetUpdated="True"/>
</DataGrid.RowValidationRules>

XAML with correct behavior:

<DataGrid.RowValidationRules>
    <rules:InvalidFedFromRule ValidatesOnTargetUpdated="True" ValidationStep="CommittedValue"/>
</DataGrid.RowValidationRules>
  • Related