ReturnOldValuesToRow() ?

5 posts, 0 answers
  1. haagel
    haagel avatar
    52 posts
    Member since:
    Feb 2010

    Posted 17 Nov 2010 Link to this post

    I have I problem with a RadGridView. ..

     

    I'm using the MVVM pattern and each row in the gridview is bound to its own ViewModel. At a certain point in the execution of the program I save a row to the database (this is done in the ViewModel of the row). This might have the consequence that some property in the ViewModel of the row is updated. Therefore I trigger the PropertyChanged event without specifying a property name, which will tell the row in the GUI to read the values of all the properties it is bound to.

     

    My problem is that sometimes when I do this, the gridview tries to set the old values of the properties back to the ViewModel. Let's say I have a column bound to a property "Age" that has the value 34; then it will set the value of the property to 34. Normally, this is not a problem (since in the end the property will still have the same value). However, my rows can have one of two states, and in one of those states some of the cells/properties are not allowed to change. I enforce this in the GUI so that it is impossible to change a value of a cell/property that is not allowed to change. But to really make sure this never happens (in case some developer makes a mistake in the GUI), I throw an exception in the ViewModel if you try:

     

    public int Age
    {
        get { return _age; }
        set
        {
            if(IsAllowedToChangeAge)
            {
                if(value != _age)
                {
                    _age = value;
                    OnPropertyChanged("Age");
                }
            }
            else
            {
                //The GUI should make sure this never happens.
                throw new Exception("Cannot change age if...");
            }
        }
    }

     

    This works fine in normal cases because the GUI makes sure it never happens. In the example above, the user won't be able to edit the cell bound to Age if the IsAllowedToChangeAge property is false.

     

    BUT as mentioned, sometimes when the ViewModel tells the gridview to update (through the PropertyChanged event), the gridview itself tries to set the values of the grid (to the same values as it had). When this happens and and the row is in a state that doesn't permit the values to change, the exception will be thrown!

     

    How can I get around this? Why does the gridview set the same values as it already has? Can I stop this from happening? I have not found a pattern for when it happens...

     

    I could get around this by not throwing an exception, but I'd really like to keep it to catch any developer mistakes.

     

    Thanks // David

  2. haagel
    haagel avatar
    52 posts
    Member since:
    Feb 2010

    Posted 17 Nov 2010 Link to this post

    Here the callstack that I got one time when the exception was thrown:

    (Bottom of the stack omitted. This is the call stack after the PropertyChanged event was triggered. Also, the top row is edited to be like my example above).

    ----

    MyRowViewModel.Age.set(string value = 34) Line 667   C#
         [External Code]   
         Telerik.Windows.Data.dll!Telerik.Windows.Data.ItemPropertyInfoExtensions.SetValue(System.ComponentModel.ItemPropertyInfo itemProperty = {System.ComponentModel.ItemPropertyInfo}, object item = {Norra.Nessie.View.MaskinPlanering.MaskinPlaneringsUppdrag}, object value = "00800") Line 85   C#
         Telerik.Windows.Controls.GridView.dll!Telerik.Windows.Controls.GridView.GridViewDataControl.ReturnOldValuesToRow(Telerik.Windows.Controls.GridViewColumnCollection columns = Count = 36, System.Collections.Generic.Dictionary<string,object> oldValues = Count = 36, object dataItem = {Norra.Nessie.View.MaskinPlanering.MaskinPlaneringsUppdrag}) Line 986 + 0xbc bytes   C#
         Telerik.Windows.Controls.GridView.dll!Telerik.Windows.Controls.GridView.GridViewDataControl.CancelRowEdit(Telerik.Windows.Controls.GridView.GridViewRow gridViewRow = {Telerik.Windows.Controls.GridView.GridViewRow}) Line 955   C#
         Telerik.Windows.Controls.GridView.dll!Telerik.Windows.Controls.GridView.GridViewDataControl.CancelEdit(Telerik.Windows.Controls.GridViewEditingUnit editingUnit = Row) Line 947   C#
         Telerik.Windows.Controls.GridView.dll!Telerik.Windows.Controls.GridView.GridViewDataControl.CancelEdit() Line 938   C#
         Telerik.Windows.Controls.GridView.dll!Telerik.Windows.Controls.GridView.GridViewDataControl.ItemsSourceChanged(bool sourceChanged = false) Line 3388   C#
         Telerik.Windows.Controls.GridView.dll!Telerik.Windows.Controls.GridView.GridViewDataControl.OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 8457 + 0xa bytes   C#
         Telerik.Windows.Controls.GridView.dll!Telerik.Windows.Controls.GridView.BaseItemsControl.OnItemCollectionChanged(object sender = {Telerik.Windows.Data.DataItemCollection}, System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 686   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.DataItemCollection.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 639   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.DataItemCollection.Telerik.Windows.Data.IWeakEventListener<System.Collections.Specialized.NotifyCollectionChangedEventArgs>.ReceiveWeakEvent(object sender = {Telerik.Windows.Data.QueryableCollectionView}, System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 1010 + 0xc bytes   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.WeakEvent.WeakListener<System.Collections.Specialized.NotifyCollectionChangedEventArgs>.Handler(object sender = {Telerik.Windows.Data.QueryableCollectionView}, System.Collections.Specialized.NotifyCollectionChangedEventArgs args = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 32 + 0x42 bytes   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 575   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.RefreshOverride() Line 719   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.RefreshInternal() Line 666   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.RefreshOrDefer() Line 661   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.ProcessSynchronousCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 938 + 0x8 bytes   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.ProcessCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 881   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.OnSourceCollectionChanged(object sender = {System.Windows.Data.BindingListCollectionView}, System.Collections.Specialized.NotifyCollectionChangedEventArgs args = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 1216   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.Telerik.Windows.Data.IWeakEventListener<System.Collections.Specialized.NotifyCollectionChangedEventArgs>.ReceiveWeakEvent(object sender = {System.Windows.Data.BindingListCollectionView}, System.Collections.Specialized.NotifyCollectionChangedEventArgs args = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 1200   C#
         Telerik.Windows.Data.dll!Telerik.Windows.Data.WeakEvent.WeakListener<System.Collections.Specialized.NotifyCollectionChangedEventArgs>.Handler(object sender = {System.Windows.Data.BindingListCollectionView}, System.Collections.Specialized.NotifyCollectionChangedEventArgs args = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 32 + 0x42 bytes   C#
  3. UI for WPF is Visual Studio 2017 Ready
  4. haagel
    haagel avatar
    52 posts
    Member since:
    Feb 2010

    Posted 22 Nov 2010 Link to this post

    No response at all?!
  5. Vlad
    Admin
    Vlad avatar
    11100 posts

    Posted 23 Nov 2010 Link to this post

    Hi,

     You can avoid this if you call CancelEdit() for the grid before setting IsAllowedToChangeAge to false. 

    Kind regards,
    Vlad
    the Telerik team
    Browse the videos here>> to help you get started with RadControls for WPF
  6. haagel
    haagel avatar
    52 posts
    Member since:
    Feb 2010

    Posted 04 Jan 2011 Link to this post

    In case someone has the same problem - I solved it by rewriting the property like this:

    public int Age
    {
        get { return _age; }
        set
        {
            if (value != _age)
            {
                if (IsAllowedToChangeAge)
                {
                    _age = value;
                    OnPropertyChanged("Age");
                }
                else
                {
                    //The GUI should make sure this never happens.
                    throw new Exception("Cannot change age if...");
                }
            }
        }
    }

    That is, I now check if the value is new first, and only if the value is new I check if it is allowed to change. That way, when the GridView tries to push in the same old value again it is just ignored.
Back to Top
UI for WPF is Visual Studio 2017 Ready