How to propagate property change notifications of objects within collections

Error

Lets say I have classes like this

public class R
{
    protected string name;
    protected List<S> listOfObjectS;
}

public class S
{
    private string name, ID;
    private A objectA;
}

public class A
{
    private string name;
    private int count;
}

If a user has two views open, one displaying instances of R and another allowing users to modify an instance of A, I need the view of R to change when the user changes any instance of A.

If the user changes a property of an instance of A, what is the best way to propagate that change (through instances of S) so that all instances of R display the new state of A?

David Schwartz

EDIT: Overhauling this answer to be more specific to the question since the tags show you already knew about INotifyPropertyChanged.

You need to implement INotifyPropertyChanged in class A and in class S. Make it so objectA can only be set through a property that will raise the PropertyChanged event on S whenever a property is changed in A. Example:

public class A : INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; OnPropertyChanged("Name"); }
    }

    private int count;

    public int Count
    {
        get { return count; } 
        set { count = value; OnPropertyChanged("Count"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

... and class S...

public class S : INotifyPropertyChanged
{
    private string name, ID;
    private A objectA;

    public A ObjectA
    {
        get { return objectA; }
        set
        {
            var old = objectA;
            objectA = value;

            // Remove the event subscription from the old instance.
            if (old != null) old.PropertyChanged -= objectA_PropertyChanged;

            // Add the event subscription to the new instance.
            if (objectA != null) objectA.PropertyChanged += objectA_PropertyChanged;

            OnPropertyChanged("ObjectA");
        }
    }

    void objectA_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // Propagate the change to any listeners. Prefix with ObjectA so listeners can tell the difference.
        OnPropertyChanged("ObjectA." + e.PropertyName);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

For class R, use ObservableCollection<S> instead of List<S>, and subscribe to its CollectionChanged event, and monitor when objects are added or removed to listOfObjectS. When they are added, subscribe to S's PropertyChanged events. Then updated R's view. Example:

public class R
{
    protected string name;
    protected System.Collections.ObjectModel.ObservableCollection<S> ListOfObjectS { get; private set; }

    public R()
    {
        // Use ObservableCollection instead.
        ListOfObjectS = new ObservableCollection<S>();

        // Subscribe to all changes to the collection.
        ListOfObjectS.CollectionChanged += listOfObjectS_CollectionChanged;
    }

    void listOfObjectS_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            // When items are removed, unsubscribe from property change notifications.
            var oldItems = (e.OldItems ?? new INotifyPropertyChanged[0]).OfType<INotifyPropertyChanged>();
            foreach (var item in oldItems)
                item.PropertyChanged -= item_PropertyChanged;
        }

        // When item(s) are added, subscribe to property notifications.
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            var newItems = (e.NewItems ?? new INotifyPropertyChanged[0]).OfType<INotifyPropertyChanged>();
            foreach (var item in newItems)
                item.PropertyChanged += item_PropertyChanged;
        }

        // NOTE: I'm not handling NotifyCollectionChangedAction.Reset.
        // You'll want to look into when this event is raised and handle it
        // in a special fashion.
    }

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName.StartsWith("ObjectA."))
        {
            // Refresh any dependent views, forms, controls, whatever...
        }
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How To Change A Property In An Array Of Objects

From Dev

Testing an objects property change within a spec with karma-jasmine

From Dev

How to script a schema change for one of my Mongo collections within Meteor

From Dev

In F#, how to change a property of a property within a record (Syntax?)

From Dev

C# and property change notifications

From Dev

How to change property of other objects in QML

From Dev

How can I change the property value in subclass within swift?

From Dev

How to subscribe to the property change of an object referenced within another object in rxjs

From Dev

Distinct objects from property GS collections Java

From Dev

Collections.sort by a date property on the objects in a list

From Dev

How can I change the name property of the objects in my mutable array?

From Dev

How to propagate change event up the component hierarchy react.js?

From Dev

Filtering an array of objects by an object property within an object within the array

From Dev

How to rank objects by property?

From Dev

Change a custom document property within Word

From Dev

reactJs setState change property on object within an array within an array

From Dev

Propagate CoreData changes to related objects

From Dev

How to rearrange objects within a list

From Dev

How to compare two generic objects with nested collections

From Dev

Laravel 5.1 How to join two collections of objects

From Dev

How to group by objects in java using collections?

From Dev

How to correctly copy collections with objects in Java

From Dev

How to group by objects in java using collections?

From Dev

Protractor: How should I propagate an error from within browser.executeAsync?

From Dev

How do I propagate updates to all items within a Colectica DDI item graph?

From Dev

Protractor: How should I propagate an error from within browser.executeAsync?

From Dev

Xcode: How to change App Name for Notifications Center

From Dev

How to change a property in for loop

From Dev

How change the property of gridslide

Related Related

  1. 1

    How To Change A Property In An Array Of Objects

  2. 2

    Testing an objects property change within a spec with karma-jasmine

  3. 3

    How to script a schema change for one of my Mongo collections within Meteor

  4. 4

    In F#, how to change a property of a property within a record (Syntax?)

  5. 5

    C# and property change notifications

  6. 6

    How to change property of other objects in QML

  7. 7

    How can I change the property value in subclass within swift?

  8. 8

    How to subscribe to the property change of an object referenced within another object in rxjs

  9. 9

    Distinct objects from property GS collections Java

  10. 10

    Collections.sort by a date property on the objects in a list

  11. 11

    How can I change the name property of the objects in my mutable array?

  12. 12

    How to propagate change event up the component hierarchy react.js?

  13. 13

    Filtering an array of objects by an object property within an object within the array

  14. 14

    How to rank objects by property?

  15. 15

    Change a custom document property within Word

  16. 16

    reactJs setState change property on object within an array within an array

  17. 17

    Propagate CoreData changes to related objects

  18. 18

    How to rearrange objects within a list

  19. 19

    How to compare two generic objects with nested collections

  20. 20

    Laravel 5.1 How to join two collections of objects

  21. 21

    How to group by objects in java using collections?

  22. 22

    How to correctly copy collections with objects in Java

  23. 23

    How to group by objects in java using collections?

  24. 24

    Protractor: How should I propagate an error from within browser.executeAsync?

  25. 25

    How do I propagate updates to all items within a Colectica DDI item graph?

  26. 26

    Protractor: How should I propagate an error from within browser.executeAsync?

  27. 27

    Xcode: How to change App Name for Notifications Center

  28. 28

    How to change a property in for loop

  29. 29

    How change the property of gridslide

HotTag

Archive