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
In the first example, setting the item in the collection will fire the CollectionChanged event, not the PropertyChanged event of the individual item.
You can notify all properties by specifying an empty string to the PropertyChanged event. For example:
item.RaisePropertyChanged("");
where RaisePropertyChanged is a public method that invokes the PropertyChanged event of the INotifyPropertyChanged implementation.
The Device class have to implement the interface INotifyPropertyChanged .Then for each property fire the notify property changed event as usuall.
This will enable the property changed notification automatically.
I think you can overload =
operator and do the assignment of properties there. then the PropertyChanged events will be generated and you will still have the same syntax as in first example.
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<T>(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.