Пример #1
0
        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);
                }
            }
        }