0

i want to build a class from which i can derive. The class should establish a logic so that it tunnels propertychanged events from Propertys who itself are classes which have Propertys.

So Please look at the Code. The goal is to throw the ListChanged Event from the BindingList when i change catList[0].MyPerson.Name = "Peter"; to Peter.

My Problem is that I dont know how i get the Class which implements NestedPropertyHolder when im in NestedPropertyHolder. In other words how i get my inheritor.... Hope you understand what im trying to do.

static void Main(string[] args)
        {
            BindingList<Category> catList = new BindingList<Category>();
            catList.ListChanged += CatList_ListChanged;
            Category cat = new Category();
            Person pers = new Person();
            pers.Name = "Rene";
            cat.MyPerson = pers;
            catList.Add(cat);

            catList[0].MyPerson.Name = "Peter";
}

 public class NestedPropertyHolder
 {
        public NestedPropertyHolder()
        {
            //List of Propertys of the class that is deriving from NestedPropertyHolder -> Should have "MyPerson" from Category
            List<object> listOfPropertysImplementingINotifyPropertyChanged = new List<object>();

            for(int i = 0; i < listOfPropertysImplementingINotifyPropertyChanged.Count; i++)
            {
                if(listOfPropertysImplementingINotifyPropertyChanged[i] is INotifyPropertyChanged)
                {
                    (listOfPropertysImplementingINotifyPropertyChanged[i] as INotifyPropertyChanged).PropertyChanged += NestedPropertyHolder_PropertyChanged;
                }
            }
        }

        private void NestedPropertyHolder_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //That class that is deriving from NestedPropertyHolder -> should be "Category"
            object classThatDerivedFromThisClass = new object();

            //classThatDerivedFromThisClass.PropertyChanged(sender, e.PropertyName);
        }
    }
}
    public class Category : NestedPropertyHolder, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        Person myPerson = new Person();

        public Person MyPerson
        {
            get
            {
                return myPerson;
            }

            set
            {
                myPerson = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyPerson"));
            }
        }
    }

    public class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        string name;

        public string Name
        {
            get
            {
                return name;
            }

            set
            {
                name = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
            }
        }
    }

Thanks for your help :)

Update: Found a interesting thread on the same topic When nesting properties that implement INotifyPropertyChanged must the parent object propogate changes?

Fabian
  • 63
  • 11
  • 1
    "The goal is to throw the ListChanged Event from the BindingList when i change" No. Do not do that. If you want to observe changes in items of a collection, hook up observer to the notification of indidividual items. DO NOT! Try to aggregate changes in the parent. – Euphoric Mar 28 '18 at 08:50
  • What do you mean with "hook up observer to the notification of indidividual items" ? What is a observer ? Do you have any Samples ? ^^ – Fabian Mar 28 '18 at 10:18
  • Observer is the code that subscribes to the event. – Euphoric Mar 28 '18 at 10:37
  • If i understand you right you want me to subscribe to the changed events of the propertys directly and not get noticed about them by the event of the list ? Why not ? I think this is elegant ? Because i have to redraw the list if any of its inner elements changes. – Fabian Mar 28 '18 at 10:53

1 Answers1

0

You could register/subscribe the PropertyChangedEvent of the class and raise it.

example:

public class Category : NestedPropertyHolder, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    Person myPerson;

    public void SomethingChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyPerson"));        
    }

    public Person MyPerson
    {
        get
        {
            return myPerson;
        }

        set
        {
            myPerson = value;
            myPerson.PropertyChanged += SomethingChanged;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyPerson"));
        }
    }
}
Mardukar
  • 415
  • 2
  • 11
  • That would stop raising the event once the `MyPerson` property gets a new value... – Zohar Peled Mar 28 '18 at 09:05
  • 1
    That's better. Now you just need to change the terminology - catch and rethrow is for exceptions. Events are being registered to and raised. – Zohar Peled Mar 28 '18 at 09:38
  • @ZoharPeled, I'd prefer *subscribe*, though [register](https://learn.microsoft.com/en-us/dotnet/standard/events/) seems to be fine too ;) Note: regarding *raised* in [guidelines](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/event) they specifically mentioned do not use synonyms. – Sinatr Mar 28 '18 at 09:47
  • It is a solution. But i dont want to do this manuell for every property. Exactly this is why i want to derive from "NestedPropertyHolder". The NestedPropertyHolder should do this to his inheritors and every property in them ! :) – Fabian Mar 28 '18 at 10:25
  • Changed the terminology ;) – Mardukar Mar 28 '18 at 10:50
  • If you want to do it dynamicly you can make `NestedPropertyHolder` abstract with an abstract method `GetInstance` which simply returns `this`. In your `NestedPropertyHolder` you can call this method and get the properties of the returned instance via reflection. Subscribing to the PropertyChanged-Event should be possible, too. This is just an idea. Didn't test it. – Mardukar Mar 28 '18 at 11:00
  • @Mardukar I'd consider using Generics instead of (or in addition too) an Abstract class. No need to create a sub-class for every possible object it could hold. – Bradley Uffner Mar 28 '18 at 11:02
  • You mean the `GetInstance` method? I think you can return a `object` there and still get the properties of "Category", "Person" ... via reflection – Mardukar Mar 28 '18 at 11:12
  • Danke Mardukar, so werde ich es mal versuchen umzusetzen. – Fabian Mar 28 '18 at 11:42