Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to get property name from the sender object of an INotifyPropertyChanged PropertyChanged event
    text
    copied!<p>I have a base DependencyObject class where I have a method that takes an object, gets the properties, and for each property that is a type that implements INotifyPropertyChanged, I add a new PropertyChangedEventHandler. Now in the handler method, it gets the parameters of an object "sender" and the PropertyChangedEventArgs "e". My question is, does anyone know how to dynamically get the property name if sender is a property of a type that implements the INotifyPropertyChanged.</p> <p>Here is what I'm working with:</p> <pre><code>public class BaseDependencyObject : DependencyObject, INotifyPropertyChanged { public BaseDependencyObject() { } protected void SetValues(Object thisObject, Object entity) { try { PropertyInfo[] properties = entity.GetType().GetProperties(); foreach (PropertyInfo property in properties) { var value = property.GetValue(entity, null); var valueIsEntity = value is System.ServiceModel.DomainServices.Client.Entity; var thisObjectsProperty = thisObject.GetType().GetProperty(property.Name); if (thisObjectsProperty != null &amp;&amp; value != null) { if (valueIsEntity) { if (thisObjectsProperty.PropertyType.GetInterface("INotifyPropertyChanged", true) != null) { var propertyInstance = Activator.CreateInstance(thisObjectsProperty.PropertyType); ((INotifyPropertyChanged)propertyInstance).PropertyChanged += new PropertyChangedEventHandler(Object_PropertyChanged); } SetValues(thisObjectsProperty, value); } else if (thisObjectsProperty.PropertyType.GetInterface("ICollection", true) != null &amp;&amp; thisObjectsProperty.PropertyType.GetGenericArguments().Count() &gt; 0) { Type genericType = thisObjectsProperty.PropertyType.GetGenericArguments()[0]; var observableCollection = Activator.CreateInstance(thisObjectsProperty.PropertyType) as IList; if (observableCollection is INotifyCollectionChanged) ((INotifyCollectionChanged)observableCollection).CollectionChanged += this.Object_CollectionChanged; if (observableCollection is INotifyPropertyChanged) ((INotifyPropertyChanged)observableCollection).PropertyChanged += new PropertyChangedEventHandler(Object_PropertyChanged); foreach (var item in (IEnumerable)value) { var newItem = Activator.CreateInstance(genericType); if (newItem != null) { SetValues(newItem, item); observableCollection.Add(newItem); } } } else { thisObjectsProperty.SetValue(thisObject, value, null); } } } } catch (Exception ex) { throw ex; } } protected void Object_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: foreach (var item in e.NewItems) { if (item is INotifyPropertyChanged) { ((INotifyPropertyChanged)item).PropertyChanged += new PropertyChangedEventHandler(Object_PropertyChanged); } } break; case NotifyCollectionChangedAction.Remove: foreach (var item in e.OldItems) { if (item is INotifyPropertyChanged) { ((INotifyPropertyChanged)item).PropertyChanged -= this.Object_PropertyChanged; } } break; } } protected void Object_PropertyChanged(object sender, PropertyChangedEventArgs e) { this.NotifyPropertyChanged(e.PropertyName); } public event PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } </code></pre> <p>The SetValues method's first param is the DependencyObject type that will be used in the view model. The second param is the entity that is being returned from the DomainService's Context.LoadOperation.</p> <p>What my issue boils down to is when the INotifyCollectionChanged.CollectionChanged fires I'm needing to be able to raise the PropertyChanged event with the collection's property name. So if anyone has any advise I would greatly appreciate it. Thanks in advance.</p> <p><strong>Edit</strong><br> Figured out how to get the properties name that is firing the event. Here is an edited version of my PropertyChangedEventHandler.</p> <pre><code>protected void Object_PropertyChanged(object sender, PropertyChangedEventArgs e) { var properties = this.GetType().GetProperties().Where(x =&gt; x.PropertyType == sender.GetType()).ToArray(); foreach (var property in properties) { this.NotifyPropertyChanged(property.Name); } //this.NotifyPropertyChanged(e.PropertyName); } </code></pre> <p>Basically this does what I was looking for, but aparentyly I am still not doing something right. The UIElement is still not updating when the ObservableCollection that is a property of another type is being added to. </p> <p>Here is an example of my DependencyObjects and ViewModel: </p> <pre><code>public class LOB : DependencyObject { public Int32 ID { get { return (Int32)GetValue(IDProperty); } set { SetValue(IDProperty, value); NotifyPropertyChanged("ID"); } } public static readonly DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(Int32), typeof(LOB), null); public ObservableCollection&lt;Group&gt; Groups { get { return (ObservableCollection&lt;Group&gt;)GetValue(GroupsProperty); } set { SetValue(GroupsProperty, value); NotifyPropertyChanged("Groups"); } } public static readonly DependencyProperty GroupsProperty = DependencyProperty.Register("Groups", typeof(ObservableCollection&lt;Group&gt;), typeof(LOB), new PropertyMetadata(null, OnGroupsPropertyChanged)); static void OnGroupsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { if (e.NewValue != null) { ((INotifyCollectionChanged)e.NewValue).CollectionChanged += new NotifyCollectionChangedEventHandler(((LOB)obj).Object_CollectionChanged); ((INotifyPropertyChanged)e.NewValue).PropertyChanged += new PropertyChangedEventHandler(((LOB)obj).Object_PropertyChanged); } if (e.OldValue != null) { ((INotifyCollectionChanged)e.OldValue).CollectionChanged -= ((LOB)obj).Object_CollectionChanged; ((INotifyPropertyChanged)e.OldValue).PropertyChanged -= ((LOB)obj).Object_PropertyChanged; } } } public class Group : DependencyObject { public Int32 ID { get { return (Int32)GetValue(IDProperty); } set { SetValue(IDProperty, value); NotifyPropertyChanged("ID"); } } public static readonly DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(Int32), typeof(Group), null); public String GroupName { get { return (String)GetValue(GroupNameProperty); } set { SetValue(GroupNameProperty, value); NotifyPropertyChanged("GroupName"); } } public static readonly DependencyProperty GroupNameProperty = DependencyProperty.Register("GroupName", typeof(String), typeof(Group), null); } public class MyViewModel : DependencyObject { public static readonly DependencyProperty LobCollectionProperty = DependencyProperty.Register("LobCollection", typeof(ObservableCollection&lt;LOB&gt;), typeof(MyViewModel), new PropertyMetadata(null, LobCollectionPropertyChanged)); public ObservableCollection&lt;LOB&gt; LobCollection { get { return (ObservableCollection&lt;MainBusinessLine&gt;)GetValue(LobCollectionPropertyChanged); } set { SetValue(MainBusinessLineCollectionProperty, value); NotifyPropertyChanged("LobCollection"); } } static void LobCollectionPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { var viewModel = obj as MyViewModel; if (viewModel == null) return; if (e.OldValue != null) { ((INotifyCollectionChanged)e.OldValue).CollectionChanged -= viewModel.LobCollection_Changed; } if (e.NewValue != null) { ((INotifyCollectionChanged)e.NewValue).CollectionChanged += viewModel.LobCollection_Changed; } } void LobCollection_Changed(object sender, NotifyCollectionChangedEventArgs e) { NotifyPropertyChanged("LobCollection"); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload