// protected internal void RemoveLogicalChild(object child) { if (child != null) { // It is invalid to modify the children collection that we // might be iterating during a property invalidation tree walk. if (IsLogicalChildrenIterationInProgress) { throw new InvalidOperationException(SR.Get(SRID.CannotModifyLogicalChildrenDuringTreeWalk)); } // Child is present FrameworkObject fo = new FrameworkObject(child as DependencyObject); if (fo.Parent == this) { fo.ChangeLogicalParent(null); } // This could have been the last child, so check if we have any more children IEnumerator children = LogicalChildren; // if null, there are no children. if (children == null) { HasLogicalChildren = false; } else { // If we can move next, there is at least one child HasLogicalChildren = children.MoveNext(); } } }
/// <summary> /// Unregisters the name - element combination from the /// NameScope that the current element belongs to. /// </summary> /// <param name="name">Name of the element</param> public void UnregisterName(string name) { INameScope nameScope = FrameworkElement.FindScope(this); if (nameScope != null) { nameScope.UnregisterName(name); } else { throw new InvalidOperationException(SR.Get(SRID.NameScopeNotFound, name, "unregister")); } }
/// <summary> /// This method causes the ThemeStyleProperty to be re-evaluated /// </summary> internal void UpdateThemeStyleProperty() { if (IsThemeStyleUpdateInProgress == false) { IsThemeStyleUpdateInProgress = true; try { StyleHelper.GetThemeStyle(/* fe = */ this, /* fce = */ null); // Update the ContextMenu and ToolTips separately because they aren't in the tree ContextMenu contextMenu = GetValueEntry( LookupEntry(ContextMenuProperty.GlobalIndex), ContextMenuProperty, null, RequestFlags.DeferredReferences).Value as ContextMenu; if (contextMenu != null) { TreeWalkHelper.InvalidateOnResourcesChange(contextMenu, null, ResourcesChangeInfo.ThemeChangeInfo); } DependencyObject toolTip = GetValueEntry( LookupEntry(ToolTipProperty.GlobalIndex), ToolTipProperty, null, RequestFlags.DeferredReferences).Value as DependencyObject; if (toolTip != null) { FrameworkObject toolTipFO = new FrameworkObject(toolTip); if (toolTipFO.IsValid) { TreeWalkHelper.InvalidateOnResourcesChange(toolTipFO.FE, toolTipFO.FCE, ResourcesChangeInfo.ThemeChangeInfo); } } OnThemeChanged(); } finally { IsThemeStyleUpdateInProgress = false; } } else { throw new InvalidOperationException(SR.Get(SRID.CyclicThemeStyleReferenceDetected, this)); } }
// protected internal void AddLogicalChild(object child) { if (child != null) { // It is invalid to modify the children collection that we // might be iterating during a property invalidation tree walk. if (IsLogicalChildrenIterationInProgress) { throw new InvalidOperationException(SR.Get(SRID.CannotModifyLogicalChildrenDuringTreeWalk)); } // Now that the child is going to be added, the FE/FCE construction is considered finished, // so we do not expect a change of InheritanceBehavior property, // so we can pick up properties from styles and resources. TryFireInitialized(); bool exceptionThrown = true; try { HasLogicalChildren = true; // Child is present; reparent him to this element FrameworkObject fo = new FrameworkObject(child as DependencyObject); fo.ChangeLogicalParent(this); exceptionThrown = false; } finally { if (exceptionThrown) { // // Consider doing this... //RemoveLogicalChild(child); } } } }
/// <summary> /// This method causes the StyleProperty to be re-evaluated /// </summary> internal void UpdateStyleProperty() { if (!HasStyleInvalidated) { if (IsStyleUpdateInProgress == false) { IsStyleUpdateInProgress = true; try { InvalidateProperty(StyleProperty); HasStyleInvalidated = true; } finally { IsStyleUpdateInProgress = false; } } else { throw new InvalidOperationException(SR.Get(SRID.CyclicStyleReferenceDetected, this)); } } }
/// <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)); } // 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(); }