/// <summary> /// Notification that is called by Measure of a child when /// it ends up with different desired size for the child. /// </summary> /// <remarks> /// Default implementation simply calls invalidateMeasure(), assuming that layout of a /// parent should be updated after child changed its size.<para/> /// Finer point: this method can only be called in the scenario when the system calls Measure on a child, /// not when parent calls it since if parent calls it, it means parent has dirty layout and is recalculating already. /// </remarks> protected virtual void OnChildDesiredSizeChanged(UIElement child) { if (IsMeasureValid) InvalidateMeasure(); }
/// <summary> /// OnChildrenChanged is called when the UIElementCollection of the UIElement is edited. /// </summary> protected internal virtual void OnChildrenChanged(UIElement added, UIElement removed, int indexAffected) { //Child visibility can't change if parent isn't visible if ((this._flags & Flags.IsVisibleCache) != 0) { if (removed != null && removed._visibility == Visibility.Visible) { removed._flags &= ~Flags.IsVisibleCache; removed.OnIsVisibleChanged(true); } if (added != null && added._visibility == Visibility.Visible) { added._flags |= Flags.IsVisibleCache; added.OnIsVisibleChanged(false); } } }
/// <summary> /// Recursively resets IsLayoutSuspended flag on all visuals of the whole v's sub tree. /// For UIElements also re-inserts the UIElement into Measure and / or Arrange update queues /// if necessary. /// </summary> internal static void PropagateResumeLayout(UIElement e) { if ((e._flags & Flags.IsLayoutSuspended) != 0) { e._flags &= ~Flags.IsLayoutSuspended; Debug.Assert((e._flags & (Flags.MeasureInProgress | Flags.ArrangeInProgress)) == 0); bool requireMeasureUpdate = ((e._flags & Flags.InvalidMeasure) != 0) && ((e._flags & Flags.NeverMeasured) == 0); bool requireArrangeUpdate = ((e._flags & Flags.InvalidArrange) != 0) && ((e._flags & Flags.NeverArranged) == 0); LayoutManager layoutManager = (requireMeasureUpdate || requireArrangeUpdate) ? LayoutManager.From(e.Dispatcher) : null; if (requireMeasureUpdate) { layoutManager.MeasureQueue.Add(e); } if (requireArrangeUpdate) { layoutManager.ArrangeQueue.Add(e); } UIElementCollection children = e._logicalChildren; if (children != null) { int count = children.Count; for (int i = 0; i < count; i++) { UIElement child = children[i]; if (child != null) { PropagateResumeLayout(child); } } } } }
/// <summary> /// Recursively propagates IsLayoutSuspended flag down to the whole v's sub tree. /// </summary> internal static void PropagateSuspendLayout(UIElement v) { if ((v._flags & Flags.IsLayoutSuspended) == 0) { v._flags |= Flags.IsLayoutSuspended; UIElementCollection children = v._logicalChildren; if (children != null) { int count = children.Count; for (int i = 0; i < count; i++) { UIElement child = children[i]; if (child != null) PropagateSuspendLayout(child); } } } }
internal static void PropagateFlags(UIElement e, Flags flags) { while ((e != null) && ((e._flags & flags) == 0)) { e._flags |= flags; if ((e._flags & Flags.ShouldPostRender) != 0) { MediaContext.From(e.Dispatcher).PostRender(); } e = e._parent; } }