예제 #1
0
        // NOTE:  The code here is highly similar to AddChildCore in ModelVisual3D,
        //        but slightly different because the parent is 2D here.
        void IVisual3DContainer.AddChild(Visual3D child)
        {
            // It is invalid to modify the children collection that we
            // might be iterating during a property invalidation tree walk.
            if (IsVisualChildrenIterationInProgress)
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotModifyVisualChildrenDuringTreeWalk));
            }

            // invalid during a VisualTreeChanged event
            VisualDiagnostics.VerifyVisualTreeChange(this);

            Debug.Assert(child != null);
            Debug.Assert(child.InternalVisualParent == null);

            child.SetParent(this);

            // set the inheritance context so databinding, etc... work
            if (_inheritanceContextForChildren != null)
            {
                _inheritanceContextForChildren.ProvideSelfAsInheritanceContext(child, null);
            }

            SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);

            // The child already might be dirty. Hence we need to propagate dirty information
            // from the parent and from the child.
            Visual.PropagateFlags(
                this,
                VisualFlags.IsSubtreeDirtyForPrecompute,
                VisualProxyFlags.IsSubtreeDirtyForRender);

            Visual3D.PropagateFlags(
                child,
                VisualFlags.IsSubtreeDirtyForPrecompute,
                VisualProxyFlags.IsSubtreeDirtyForRender);

            //


            // Fire notifications
            OnVisualChildrenChanged(child, /* visualRemoved = */ null);

            child.FireOnVisualParentChanged(null);
            VisualDiagnostics.OnVisualChildChanged(this, child, true);
        }
예제 #2
0
        /// <summary>
        ///     Invoked when logical parent is changed.  This just
        ///     sets the parent pointer.
        /// </summary>
        /// <remarks>
        ///     A parent change is considered catastrohpic and results in a large
        ///     amount of invalidations and tree traversals. <cref see="DependencyFastBuild"/>
        ///     is recommended to reduce the work necessary to build a tree
        /// </remarks>
        /// <param name="newParent">
        ///     New parent that was set
        /// </param>
        internal void ChangeLogicalParent(DependencyObject newParent)
        {
            ///////////////////
            // OnNewParent:
            ///////////////////

            //
            // -- Approved By The Core Team --
            //
            // Do not allow foreign threads to change the tree.
            // (This is a noop if this object is not assigned to a Dispatcher.)
            //
            // We also need to ensure that the tree is homogenous with respect
            // to the dispatchers that the elements belong to.
            //
            this.VerifyAccess();
            if (newParent != null)
            {
                newParent.VerifyAccess();
            }

            // Logical Parent must first be dropped before you are attached to a newParent
            // This mitigates illegal tree state caused by logical child stealing as illustrated in bug 970706
            if (_parent != null && newParent != null && _parent != newParent)
            {
                throw new System.InvalidOperationException(SR.Get(SRID.HasLogicalParent));
            }

            // Trivial check to avoid loops
            if (newParent == this)
            {
                throw new System.InvalidOperationException(SR.Get(SRID.CannotBeSelfParent));
            }

            // invalid during a VisualTreeChanged event
            VisualDiagnostics.VerifyVisualTreeChange(this);

            // Logical Parent implies no InheritanceContext
            if (newParent != null)
            {
                ClearInheritanceContext();
            }

            IsParentAnFE = newParent is FrameworkElement;

            DependencyObject oldParent = _parent;

            OnNewParent(newParent);

            // Update Has[Loaded/Unloaded]Handler Flags
            BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag(this, oldParent, newParent);



            ///////////////////
            // OnParentChanged:
            ///////////////////

            // Invalidate relevant properties for this subtree
            DependencyObject parent = (newParent != null) ? newParent : oldParent;

            TreeWalkHelper.InvalidateOnTreeChange(/* fe = */ this, /* fce = */ null, parent, (newParent != null));

            // If no one has called BeginInit then mark the element initialized and fire Initialized event
            // (non-parser programmatic tree building scenario)
            TryFireInitialized();
        }
예제 #3
0
        // NOTE:  The code here is highly similar to RemoveChildCore in ModelVisual3D,
        //        but slightly different because the parent is 2D here.
        void IVisual3DContainer.RemoveChild(Visual3D child)
        {
            int index = child.ParentIndex;

            // It is invalid to modify the children collection that we
            // might be iterating during a property invalidation tree walk.
            if (IsVisualChildrenIterationInProgress)
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotModifyVisualChildrenDuringTreeWalk));
            }

            // invalid during a VisualTreeChanged event
            VisualDiagnostics.VerifyVisualTreeChange(this);

            Debug.Assert(child != null);
            Debug.Assert(child.InternalVisualParent == this);

            VisualDiagnostics.OnVisualChildChanged(this, child, false);

            child.SetParent(/* newParent = */ (Visual)null);   // CS0121: Call is ambigious without casting null to Visual.

            // remove the inheritance context
            if (_inheritanceContextForChildren != null)
            {
                _inheritanceContextForChildren.RemoveSelfAsInheritanceContext(child, null);
            }

            //
            // Remove the child on all channels this visual is marshalled to.
            //

            for (int i = 0, limit = _proxy3D.Count; i < limit; i++)
            {
                DUCE.Channel channel = _proxy3D.GetChannel(i);

                if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent))
                {
                    child.SetFlags(channel, false, VisualProxyFlags.IsConnectedToParent);
                    DUCE.IResource childResource = (DUCE.IResource)child;
                    childResource.RemoveChildFromParent(this, channel);
                    childResource.ReleaseOnChannel(channel);
                }
            }

            SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);

            //
            // Force a full precompute and render pass for this visual.
            //

            Visual.PropagateFlags(
                this,
                VisualFlags.IsSubtreeDirtyForPrecompute,
                VisualProxyFlags.IsSubtreeDirtyForRender);

            //


            child.FireOnVisualParentChanged(this);

            OnVisualChildrenChanged(/* visualAdded = */ null, child);
        }