How to check if any cell was modified in RowValidating event handler

6 posts, 2 answers
  1. AlexPinsker
    AlexPinsker avatar
    3 posts
    Member since:
    Apr 2011

    Posted 12 May 2011 Link to this post

    Is it possible to check whether any cell was actually modified in RowValidating event handler.
    Probably it's possible to do it comparing all cell values with GridViewRowValidatingEventArgs.OldValues, but may be there is a better way to find it?

    Thanks
       Alex
  2. Answer
    Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 13 May 2011 Link to this post

    Hi AlexPinsker,

     On RowValidating event you could compare the e.OldValue to the values in e.Row (as you have mentioned). You can as well cast e.Row to your business object and compare e.OldValues with its properties. There is not a direct way to know if any changes have been made. 

    Basically the validation could be done on data lever as well, rather that on UI level. Could you please specify what exactly you would like to do regarding the validation, so that we could suggest you another way of validating the data? 

    All the best,
    Didie
    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
  3. UI for WPF is Visual Studio 2017 Ready
  4. AlexPinsker
    AlexPinsker avatar
    3 posts
    Member since:
    Apr 2011

    Posted 13 May 2011 Link to this post

    Hi Didie,
    I'm trying to achieve the following functionality:
    When user changed any cell in the row I want to display notification asking him to provide a reason for the change and save this reason (for auditing purposes). So, if user just entered 'edit mode' and then jumped to another row without actually changing data - I don't want to show him this notification.

    (I want to ask user only after I've validated that his changes are valid and hence I do it in RowValidating handler.  Is there a better way to achieve this functionality)?

    Thanks
       Alex
  5. Answer
    Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 16 May 2011 Link to this post

    Hello AlexPinsker,

     In your scenario you are right to use the RowValidating event. In order to avoid comparing all cell values with GridViewRowValidatingEventArgs.OldValues you could define a private variable hasChanges. Then in CellValidated event handler you could compare e.OldValue with e.NewValue and set hasChanges to the result of the comparison.

    In RowValidating after you finish your logic, you should set hasChanges back to false.

    If you have any more questions regarding the validation, please feel free to contact us!

    Regards,
    Didie
    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
  6. AlexPinsker
    AlexPinsker avatar
    3 posts
    Member since:
    Apr 2011

    Posted 16 May 2011 Link to this post

    Thanks, that's completely answers my question.
    Alex
  7. Lawrence
    Lawrence avatar
    10 posts
    Member since:
    Jul 2013

    Posted 05 Aug 2013 Link to this post

    I wrote a generic RowValidating Method that uses reflection to compare the new values against the old ones.  In this particular example, your object will need to inherit from a class that has a "Save" method.  In my case "ModelTransactionBase"       

    /// <summary>
    /// Rows the validating.
    /// </summary>
    /// <typeparam name="T">Type</typeparam>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="GridViewRowValidatingEventArgs"/> instance containing the event data.</param>
    public static void RowValidating<T>(object sender, GridViewRowValidatingEventArgs e) where T : ModelTransactionalBase
    {
        try
        {
            bool hasChanged = false;
            var entity = (T)e.Row.Item;
     
            if (e.EditOperationType == GridViewEditOperationType.Insert)
            {
                hasChanged = true;
            }
            else
            {
                Type entityType = entity.GetType();
                var properties = new List<PropertyInfo>(entityType.GetProperties());
     
                // See if the old values are different from the new ones.
                foreach (PropertyInfo propertyInfo in properties)
                {
                    foreach (KeyValuePair<string, object> value in e.OldValues)
                    {
                        if (propertyInfo.Name.Equals(value.Key))
                        {
                            Type newType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
                            var oldValue = (value.Value == null) ? null : Convert.ChangeType(value.Value, newType);
                            var newValue = propertyInfo.GetValue(entity);
     
                            if (newValue == null && oldValue == null)
                            {
                                hasChanged = false;
                                break;
                            }
                            else if (newValue == null || oldValue == null)
                            {
                                hasChanged = true;
                                break;
                            }
                            else if (value.Value.GetType() != newType)
                            {
                                hasChanged = true;
                                break;
                            }
                            else if (!propertyInfo.GetValue(entity).Equals(oldValue))
                            {
                                hasChanged = true;
                                break;
                            }
                        }
                    }
     
                    // Once one property has changed, no need to continue checking the remainder.
                    if (hasChanged)
                    {
                        break;
                    }
                }
            }
     
            if (hasChanged)
            {
                entity.Save();
            }
        }
        catch (ValidationException vex)
        {
            RadWindow.Alert(vex.Message, delegate(object windowSender, WindowClosedEventArgs args) { e.IsValid = false; });
        }
    }


    Which can be called from your RowsValidating event of your RadGridView.  "YourObject" is what's bound to the grid and inherits from what I have below as "ModelTransactionalBase".

    private void RadGridViewTemplatesRowValidating(object sender, GridViewRowValidatingEventArgs e)
    {                          
          RadGridViewHelper.RowValidating<YourObject>(sender, e);
    }

    ModelTransactionBase.  ModelBase Inherits from "Telerik.Windows.Controls.ViewModelBase", and doesn't provide any value for this example, but is specific to my application.

    internal abstract class ModelTransactionalBase : ModelBase
    { 
        #region Abstract Methods
        /// <summary>
        /// Saves this instance.
        /// </summary>
        public abstract void Save();
        #endregion
    }
Back to Top
UI for WPF is Visual Studio 2017 Ready