// 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)); } 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); }
// 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); }
/// <summary> /// DisconnectChild /// /// Derived classes must call this method to notify the Visual3D layer that a /// child was removed from the children collection. The Visual3D layer will then call /// GetVisual3DChild to find out which child has been removed. /// /// </summary> protected void RemoveVisual3DChild(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)); } Debug.Assert(child != null); Debug.Assert(child.InternalVisualParent == this); child.SetParent(/* newParent = */ (Visual3D) null); // CS0121: Call is ambigious without casting null to Visual3D. // remove the inheritance context RemoveSelfAsInheritanceContext(child, null); // // Remove the child on all the channels // this visual is being marshalled to. // for (int i = 0, limit = _proxy.Count; i < limit; i++) { DUCE.Channel channel = _proxy.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); } } // // Force a full precompute and render pass for this visual. // Visual3D.PropagateFlags( this, VisualFlags.IsSubtreeDirtyForPrecompute, VisualProxyFlags.IsSubtreeDirtyForRender); // // Fire notifications child.FireOnVisualParentChanged(this); OnVisualChildrenChanged(/* visualAdded = */ null , child); }
//------------------------------------------------------ // // Public Properties // //------------------------------------------------------ //------------------------------------------------------ // // Public Events // //------------------------------------------------------ //------------------------------------------------------ // // Protected Methods // //------------------------------------------------------ #region Protected Methods /// <summary> /// AttachChild /// /// Derived classes must call this method to notify the Visual3D layer that a new /// child appeard in the children collection. The Visual3D layer will then call the GetVisual3DChild /// method to find out where the child was added. /// /// Remark: To move a Visual3D child in a collection it must be first disconnected and then connected /// again. (Moving forward we might want to add a special optimization there so that we do not /// unmarshal our composition resources). /// </summary> protected void AddVisual3DChild(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)); } Debug.Assert(child != null); Debug.Assert(child.InternalVisualParent == null); child.SetParent(this); // set the inheritance context so databinding, etc... work ProvideSelfAsInheritanceContext(child, null); // The child already might be dirty. Hence we need to propagate dirty information // from the parent and from the child. Visual3D.PropagateFlags( this, VisualFlags.IsSubtreeDirtyForPrecompute, VisualProxyFlags.IsSubtreeDirtyForRender); Visual3D.PropagateFlags( child, VisualFlags.IsSubtreeDirtyForPrecompute, VisualProxyFlags.IsSubtreeDirtyForRender); // // Fire notifications OnVisualChildrenChanged(child, /* visualRemoved = */ null); child.FireOnVisualParentChanged(null); }