internal void OnPropertyChanged(object source, PropertyChangedEventArgs eventArgs) { Util.CheckArgumentNull(source, "source"); Util.CheckArgumentNull(eventArgs, "eventArgs"); #if DEBUG Debug.Assert(this.bindingGraph.IsTracking(source), "Entity must be part of the graph if it has the event notification registered."); #endif string sourceProperty = eventArgs.PropertyName; if (String.IsNullOrEmpty(sourceProperty)) { this.HandleUpdateEntity( source, null, null); } else { BindingEntityInfo.BindingPropertyInfo bpi; object sourcePropertyValue = BindingEntityInfo.GetPropertyValue(source, sourceProperty, out bpi); if (bpi != null) { this.bindingGraph.RemoveRelation(source, sourceProperty); switch (bpi.PropertyKind) { case BindingPropertyKind.BindingPropertyKindCollection: if (sourcePropertyValue != null) { try { typeof(BindingUtils) .GetMethod("VerifyObserverNotPresent", BindingFlags.NonPublic | BindingFlags.Static) .MakeGenericMethod(bpi.PropertyInfo.CollectionType) .Invoke(null, new object[] { sourcePropertyValue, sourceProperty, source.GetType() }); } catch (TargetInvocationException tie) { throw tie.InnerException; } try { this.AttachBehavior = true; this.bindingGraph.AddCollection( source, sourceProperty, sourcePropertyValue, null); } finally { this.AttachBehavior = false; } } break; case BindingPropertyKind.BindingPropertyKindEntity: this.bindingGraph.AddEntity( source, sourceProperty, sourcePropertyValue, null, source); break; default: Debug.Assert(bpi.PropertyKind == BindingPropertyKind.BindingPropertyKindComplex, "Must be complex type if PropertyKind is not entity or collection."); if (sourcePropertyValue != null) { this.bindingGraph.AddComplexProperty( source, sourceProperty, sourcePropertyValue); } this.HandleUpdateEntity( source, sourceProperty, sourcePropertyValue); break; } } else { this.HandleUpdateEntity( source, sourceProperty, sourcePropertyValue); } } }
internal void OnPropertyChanged(object source, PropertyChangedEventArgs eventArgs) { Util.CheckArgumentNull(source, "source"); Util.CheckArgumentNull(eventArgs, "eventArgs"); #if DEBUG Debug.Assert(this.bindingGraph.IsTracking(source), "Entity must be part of the graph if it has the event notification registered."); #endif string sourceProperty = eventArgs.PropertyName; // When sourceProperty is null, it is assumed that all properties for the object changed // As a result, we should be performing an UpdateObject operation on the context. if (String.IsNullOrEmpty(sourceProperty)) { this.HandleUpdateEntity( source, null, null); } else { BindingEntityInfo.BindingPropertyInfo bpi; // Get the new value for the changed property. object sourcePropertyValue = BindingEntityInfo.GetPropertyValue(source, sourceProperty, out bpi); // Check if it is an interesting property e.g. collection, entity reference or complex type. if (bpi != null) { // Disconnect the edge between source and original source property value. this.bindingGraph.RemoveRelation(source, sourceProperty); switch (bpi.PropertyKind) { case BindingPropertyKind.BindingPropertyKindCollection: // If collection is already being tracked by the graph we can not have > 1 links to it. if (sourcePropertyValue != null) { // Make sure that there is no observer on the input collection property. try { typeof(BindingUtils) .GetMethod("VerifyObserverNotPresent", BindingFlags.NonPublic | BindingFlags.Static) .MakeGenericMethod(bpi.PropertyInfo.CollectionType) .Invoke(null, new object[] { sourcePropertyValue, sourceProperty, source.GetType() }); } catch (TargetInvocationException tie) { throw tie.InnerException; } try { this.AttachBehavior = true; this.bindingGraph.AddCollection( source, sourceProperty, sourcePropertyValue, null); } finally { this.AttachBehavior = false; } } break; case BindingPropertyKind.BindingPropertyKindEntity: // Add the newly added entity to the graph, or update entity reference. this.bindingGraph.AddEntity( source, sourceProperty, sourcePropertyValue, null, source); break; default: Debug.Assert(bpi.PropertyKind == BindingPropertyKind.BindingPropertyKindComplex, "Must be complex type if PropertyKind is not entity or collection."); // Attach the newly assigned complex type object and it's child complex typed objects. if (sourcePropertyValue != null) { this.bindingGraph.AddComplexProperty( source, sourceProperty, sourcePropertyValue); } this.HandleUpdateEntity( source, sourceProperty, sourcePropertyValue); break; } } else { // For non-interesting properties i.e. value types or regular collection properties we simply call UpdateObject on the context. // Note that this code also handles primitive properties of complex typed objects. this.HandleUpdateEntity( source, sourceProperty, sourcePropertyValue); } } }