mattsven mattsven - 4 years ago 152
C# Question

Comparing two ObservableCollection(s) to see if they are different

I'm working on comparing two versions of a listview, for a settings form. I need to know if the user actually modified the list at all, in which case when they click "Save" I'll actually save. If they didn't change anything, when they click "Save" I won't be wasting memory/time re-saving something they didn't change.

Anyway, how can I compare two ObservableCollections to see if they are at all different?

Thanks in advance!

Answer Source

The way that we handle this requires a little more work up front, but it can be automated using VS macros or code-gen tools such as CodeSmith.

However, this approach is extensible to any UI construct that the collection is bound to and doesn't have to be re-implemented in the UI each time you need to know whether there are changes or not.

The concept is to update flags within the collection and business object to determine whether or not the collection membership has changed or any given record has changed within the collection.

The implementation is fairly simple:

Add a HasChanged property to the business object class.

Add an AnyDeleted property to the collection. This will only be set if items are deleted from the collection.

Initialize these values to false after the records are read from the DB.

(Now the semi-tedious part) For each property in the class, set the HasChanged property to true if the value actually changes. Be careful of null values. For example:

    public bool IsSelected
    {
        get
        {
            return m_fIsSelected;
        }
        set
        {
            if (m_fIsSelected != value)
            {
                this.HasChanged = true;
                m_fIsSelected = value;
            }
        }
    }

Modify the collection to set the AnyDeleted property to true when a record is deleted:

    protected override void RemoveItem(int index)
    {
        this.AnyDeleted = true;

        base.RemoveItem(index);
    }

Finally, add a method to the collection to indicate whether or not anything has changed. This is the method that you will call to determine whether or not any changes need to be saved:

   public bool HasAnyChanges()
    {
        // Exceptions are handled by the caller

        // If anything was deleted, return true
        if (this.AnyDeleted)
        {
            return true;
        }
        else
        {
            foreach (T theItem in this)
            {
                if (theItem.HasAnyChanges())
                {
                    return true;
                }
            }
        }

        return false;
    }
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download