Updating ObservableCollection Item properties using INotifyPropertyChanged

前端 未结 4 1834
小鲜肉
小鲜肉 2021-01-19 10:05

Checking to make sure my assumptions are correct.

I have an ObservableCollection class. I am calling a web service and retrieving an array of Devices. I am then enum

4条回答
  •  不要未来只要你来
    2021-01-19 10:51

    For that a Load method might be useful, so you don't overwrite the reference but set all the properties of the old object instead. Here's a generic extension method i just wrote which will assign all the writeable properties, it's very rough:

    public static class ExtensionMethods
    {
        public static void Load(this T target, Type type, T source, bool deep)
        {
            foreach (PropertyInfo property in type.GetProperties())
            {
                if (property.CanWrite && property.CanRead)
                {
                    if (!deep || property.PropertyType.IsPrimitive || property.PropertyType == typeof(String))
                    {
                        property.SetValue(target, property.GetValue(source, null), null);
                    }
                    else
                    {
                        object targetPropertyReference = property.GetValue(target, null);
                        targetPropertyReference.Load(targetPropertyReference.GetType(), property.GetValue(source, null), deep);
                    }
                }
            }
        }
    }
    

    You should then be able to call

    item.Load(item.GetType(), currentDevice, true); //false for shallow loading
    

    to assign all the values (if they are properties).

    Edit: Made the method recursive so it will call Load for properties which are not of a primitive type or value type (or string). Probably still misbehaves in some cases.
    You could also add a bool deep to the method and control if it should deep-load if that might be needed. (Just add || !deep to that long if-expression)

    Note: You could of course also overwrite your object reference and use reflection to raise the PropertyChanged event for all the different properties if you prefer. Either way you don't need to handle each property manually.

    Edit2: Because PropertyInfo.GetValue returns an object my previous code did not load recursively, unfortunately with this you have to explicitly pass a Type, see revisions for old version.

    Edit3: For ways to make this work without the Type reference see this dedicated question that i asked. This however does not address other issues like circular references and properties that enumerate objects.

提交回复
热议问题