This is a migrated thread and some comments may be shown as answers.

RadGridView binding doesn't update after validation

2 Answers 46 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Peter
Top achievements
Rank 1
Peter asked on 13 Apr 2011, 01:52 AM
Hi All,


I have a RadGridView control like this,

    <twc:RadGridView ItemsSource="{Binding Values}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedValue, Mode=TwoWay}" >
            <twc:RadGridView.Columns>
                <twc:GridViewDataColumn
                            x:Name="ValueColumn"
                            Header="Values"
                            MinWidth="100"
                            DataMemberBinding="{Binding Value, NotifyOnValidationError=True}" />
                <twc:GridViewDataColumn
                            x:Name="DescriptionColumn"
                            Header="Description"
                            MinWidth="250"
                            DataMemberBinding="{Binding Explanation}" IsReadOnly="True"/>
            </twc:RadGridView.Columns>
        </twc:RadGridView>

The first column there binds to a property like this,

    public decimal? Value
        {
            get { return _value; }
            set
            {
                _value = value;

                RaisePropertyChanged("Value");

                if (value > 200)
                {
                    throw new ValidationException("Invalid ...");
                }
            }
        }

The problem is that I enter 200 into that field, which is valid. I then enter 2000 into the field, which causes a validation exception. I then enter 200 into the field again, and the value immediately changes to 2000.

The reason is that the second time I enter 200 the control doesn't update the binding, thus the value of 'Value' in the view model doesn't get updated. This means that the control calls the getter and the value of 2000 is shown.

It is as though the control considers the value 2000 to be invalid, so the control still thinks of its original value as being 200. You then change it back to 200 and the control thinks 'oh, that's the same as it used to be, so I don't have to update the binding'.

Any ideas?

2 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 18 Apr 2011, 01:38 PM
Hello Peter,

Basically, the assumption you made on the cause of the issue is correct. What you may try in this case is to define your property as follows:

public decimal? StadiumCapacity
        {
            get { return this.stadiumCapacity; }
            set
            {
                if (value != this.stadiumCapacity)
                {
                    if (value > 200)
                    {
                        throw new ValidationException("Invalid ...");
                    }
                    this.stadiumCapacity = value;
                    this.OnPropertyChanged("StadiumCapacity");
                }
            }
        }

Thus the validation will be performed before setting the value of the property.
 

Greetings,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Peter
Top achievements
Rank 1
answered on 19 Apr 2011, 01:13 AM
Thanks. It's good to have that confirmed. I did originally try your solution, but for a different reason it doesn't work in my case.

In reality my validation is not as simple as just saying 'is the value greater than 200'. My values are in a grid, and look like this on the screen. You enter 'band values' as shown,

1
10
100

Which is valid, but this is not valid

1
100
10

I.e. they have to be in numerical order. So if each of those items has a separate view model and is a separate item in a grid, and each is being bound to a field called 'BandValue' then the backing field has to be set before we can traverse the list and make sure they are in the correct order.

So I am going to have to do something like this,

        public decimal? StadiumCapacity
        {
            get { return this.stadiumCapacity; }
            set
            {
                if (value != this.stadiumCapacity)
                {
                    int originalStadiumCapacity = this.stadiumCapacity;
 
                    this.stadiumCapacity = value;
 
                    if (ItemsOutOfOrder())
                    {
                        this.stadiumCapacity = originalStadiumCapacity;
                        throw new ValidationException("Invalid ...");
                    }
 
                    this.OnPropertyChanged("StadiumCapacity");
                }
            }
        }

So ItemsOutOfOrder actually calls an event which traverses all of the current 'stadiumCapacity' items. If 'stadiumCapacity' is not set at the time to the invalid value then it won't work.

This is a popup window, so I also have an OK and Cancel button. I am catching the grid 'CellValidated' event and storing the validation result to control whether the user can click the OK button.

But the Cancel button was not working as I needed it to. When clicking Cancel the invalid field is holding onto the focus. The best fix I came up with is making the button ClickMode = "Press".

Any better suggestions let me know.
Tags
GridView
Asked by
Peter
Top achievements
Rank 1
Answers by
Maya
Telerik team
Peter
Top achievements
Rank 1
Share this question
or