private Request _getNewRequest(UIElement e) { Request r; if (_pocket != null) { r = _pocket; _pocket = r.Next; _pocketSize--; r.Next = r.Prev = null; } else { ContextLayoutManager lm = ContextLayoutManager.From(e.Dispatcher); try { r = new Request(); } catch (System.OutOfMemoryException ex) { if (lm != null) { lm.setForceLayout(e); } throw ex; } } r.Target = e; return(r); }
internal void Add(UIElement e) { if (getRequest(e) != null) { return; } if (e.CheckFlagsAnd(VisualFlags.IsLayoutSuspended)) { return; } RemoveOrphans(e); UIElement parent = e.GetUIParentWithinLayoutIsland(); if (parent != null && canRelyOnParentRecalc(parent)) { return; } ContextLayoutManager layoutManager = ContextLayoutManager.From(e.Dispatcher); if (layoutManager._isDead) { return; } //10 is arbitrary number here, simply indicates the queue is //about to be filled. If not queue is not almost full, simply add //the element to it. If it is almost full, start conserve entries //by escalating invalidation to all the ancestors until the top of //the visual tree, and only add root of visula tree to the queue. if (_pocketSize > PocketReserve) { _addRequest(e); } else { //walk up until we are the topmost UIElement in the tree. //on each step, mark the parent dirty and remove it from the queues //only leave a single node in the queue - the root of visual tree while (e != null) { UIElement p = e.GetUIParentWithinLayoutIsland(); invalidate(e); //invalidate in any case if (p != null && p.Visibility != Visibility.Collapsed) //not yet a root or a collapsed node { Remove(e); } else //root of visual tree or a collapsed node { if (getRequest(e) == null) { RemoveOrphans(e); _addRequest(e); } } e = p; } } layoutManager.NeedsRecalc(); }