protected internal virtual void RenderRecursive(DrawingContext dc) { dc.Translate(this._offsetX, this._offsetY); dc.PushClippingRectangle(0, 0, this._renderWidth, this._renderHeight); try { if (dc.EmptyClipRect) { return; } this.OnRender(dc); UIElementCollection logicalChildren = this._logicalChildren; if (logicalChildren == null) { return; } int count = logicalChildren.Count; for (int index = 0; index < count; ++index) { UIElement uiElement = logicalChildren[index]; if (uiElement.IsRenderable()) { uiElement.RenderRecursive(dc); } } } finally { dc.PopClippingRectangle(); dc.Translate(-this._offsetX, -this._offsetY); this._flags &= ~(UIElement.Flags.IsSubtreeDirtyForRender | UIElement.Flags.IsDirtyForRender); } }
protected UIElement() { UIElement.EnsureClassHandlers(); this._flags = UIElement.Flags.Enabled | UIElement.Flags.NeverMeasured | UIElement.Flags.NeverArranged; this._visibility = Visibility.Visible; this._verticalAlignment = VerticalAlignment.Stretch; this._horizontalAlignment = HorizontalAlignment.Stretch; }
internal static void PropagateFlags(UIElement e, UIElement.Flags flags) { for (; e != null && (e._flags & flags) == UIElement.Flags.None; e = e._parent) { e._flags |= flags; if ((e._flags & UIElement.Flags.ShouldPostRender) != UIElement.Flags.None) { MediaContext.From(e.Dispatcher).PostRender(); } } }
public void InvalidateArrange() { this.VerifyAccess(); UIElement.Flags flags = this._flags; if ((flags & (UIElement.Flags.InvalidArrange | UIElement.Flags.ArrangeInProgress)) != UIElement.Flags.None) { return; } this._flags |= UIElement.Flags.InvalidArrange; if ((flags & UIElement.Flags.NeverArranged) != UIElement.Flags.None) { return; } LayoutManager.CurrentLayoutManager.ArrangeQueue.Add(this); }
public void InvalidateMeasure() { this.VerifyAccess(); UIElement.Flags flags = this._flags; if ((flags & (UIElement.Flags.InvalidMeasure | UIElement.Flags.MeasureInProgress)) != UIElement.Flags.None) { return; } this._flags |= UIElement.Flags.InvalidMeasure; if ((flags & UIElement.Flags.NeverMeasured) != UIElement.Flags.None) { return; } LayoutManager.CurrentLayoutManager.MeasureQueue.Add(this); }
public void Arrange(int finalRectX, int finalRectY, int finalRectWidth, int finalRectHeight) { this.VerifyAccess(); if ((this._flags & (UIElement.Flags.InvalidMeasure | UIElement.Flags.NeverMeasured)) != UIElement.Flags.None) { try { this._flags |= UIElement.Flags.MeasureDuringArrange; this.Measure(finalRectWidth, finalRectHeight); } finally { this._flags &= ~UIElement.Flags.MeasureDuringArrange; } } if (this.Visibility == Visibility.Collapsed || (this._flags & UIElement.Flags.IsLayoutSuspended) != UIElement.Flags.None) { LayoutManager.CurrentLayoutManager.ArrangeQueue.Remove(this); this._finalX = finalRectX; this._finalY = finalRectY; this._finalWidth = finalRectWidth; this._finalHeight = finalRectHeight; } else if ((this._flags & UIElement.Flags.InvalidArrange) == UIElement.Flags.None && (this._flags & UIElement.Flags.NeverArranged) == UIElement.Flags.None && (finalRectWidth == this._finalWidth && finalRectHeight == this._finalHeight)) { if (finalRectX == this._finalX && finalRectY == this._finalY) { return; } this._offsetX = this._offsetX - this._finalX + finalRectX; this._offsetY = this._offsetY - this._finalY + finalRectY; this._finalX = finalRectX; this._finalY = finalRectY; if (!this.IsRenderable()) { return; } UIElement.PropagateFlags(this, UIElement.Flags.IsSubtreeDirtyForRender); } else { this._flags = this._flags & ~UIElement.Flags.NeverArranged | UIElement.Flags.ArrangeInProgress; int num1 = this._marginLeft + this._marginRight; int num2 = this._marginTop + this._marginBottom; int num3 = this.HorizontalAlignment == HorizontalAlignment.Stretch ? finalRectWidth : this._desiredWidth; int num4 = this.VerticalAlignment == VerticalAlignment.Stretch ? finalRectHeight : this._desiredHeight; int arrangeWidth = num3 - num1; int arrangeHeight = num4 - num2; if (this._requestedSize != null) { if ((this._requestedSize._status & 1) != 0) { int first = this._requestedSize._first; if (first < arrangeWidth) { arrangeWidth = first; } } if ((this._requestedSize._status & 2) != 0) { int second = this._requestedSize._second; if (second < arrangeHeight) { arrangeHeight = second; } } } try { this.ArrangeOverride(arrangeWidth, arrangeHeight); } finally { this._flags &= ~UIElement.Flags.ArrangeInProgress; } int clientWidth = Math.Max(0, finalRectWidth - num1); int clientHeight = Math.Max(0, finalRectHeight - num2); int dx; int dy; if (clientWidth != arrangeWidth || clientHeight != arrangeHeight) { this.ComputeAlignmentOffset(clientWidth, clientHeight, arrangeWidth, arrangeHeight, out dx, out dy); } else { dx = dy = 0; } int num5 = dx + (finalRectX + this._marginLeft); dy += finalRectY + this._marginTop; this._offsetX = num5; this._offsetY = dy; this._renderWidth = arrangeWidth; this._renderHeight = arrangeHeight; this._finalX = finalRectX; this._finalY = finalRectY; this._finalWidth = finalRectWidth; this._finalHeight = finalRectHeight; this._flags &= ~UIElement.Flags.InvalidArrange; LayoutManager.CurrentLayoutManager.ArrangeQueue.Remove(this); if (!this.IsRenderable()) { return; } UIElement.PropagateFlags(this, UIElement.Flags.IsSubtreeDirtyForRender); } }
public void Measure(int availableWidth, int availableHeight) { this.VerifyAccess(); UIElement.Flags flags = this._flags; if (this.Visibility == Visibility.Collapsed || (flags & UIElement.Flags.IsLayoutSuspended) != UIElement.Flags.None) { LayoutManager.CurrentLayoutManager.MeasureQueue.Remove(this); this._previousAvailableWidth = availableWidth; this._previousAvailableHeight = availableHeight; } else { if ((flags & UIElement.Flags.InvalidMeasure) == UIElement.Flags.None && (flags & UIElement.Flags.NeverMeasured) == UIElement.Flags.None && (availableWidth == this._previousAvailableWidth && availableHeight == this._previousAvailableHeight)) { return; } this._flags &= ~UIElement.Flags.NeverMeasured; int desiredWidth1 = this._desiredWidth; int desiredHeight1 = this._desiredHeight; this.InvalidateArrange(); this._flags |= UIElement.Flags.MeasureInProgress; int desiredWidth2; int desiredHeight2; try { int num1 = this._marginLeft + this._marginRight; int num2 = this._marginTop + this._marginBottom; int num3 = availableWidth - num1; int num4 = availableHeight - num2; if (this._requestedSize != null) { int num5 = (uint)(this._requestedSize._status & 1) > 0U ? 1 : 0; bool flag = (uint)(this._requestedSize._status & 2) > 0U; if (num5 != 0) { num3 = Math.Min(this._requestedSize._first, num3); } if (flag) { num4 = Math.Min(this._requestedSize._second, num4); } this.MeasureOverride(num3, num4, out desiredWidth2, out desiredHeight2); if (num5 != 0) { desiredWidth2 = this._requestedSize._first; } if (flag) { desiredHeight2 = this._requestedSize._second; } } else { this.MeasureOverride(num3, num4, out desiredWidth2, out desiredHeight2); } this._unclippedWidth = desiredWidth2; this._unclippedHeight = desiredHeight2; desiredWidth2 = Math.Min(desiredWidth2, num3); desiredHeight2 = Math.Min(desiredHeight2, num4); desiredWidth2 += num1; desiredHeight2 += num2; } finally { this._flags &= ~UIElement.Flags.MeasureInProgress; this._previousAvailableWidth = availableWidth; this._previousAvailableHeight = availableHeight; } this._flags &= ~UIElement.Flags.InvalidMeasure; LayoutManager.CurrentLayoutManager.MeasureQueue.Remove(this); this._desiredWidth = desiredWidth2; this._desiredHeight = desiredHeight2; if ((this._flags & UIElement.Flags.MeasureDuringArrange) != UIElement.Flags.None || desiredWidth1 == desiredWidth2 && desiredHeight1 == desiredHeight2) { return; } UIElement parent = this._parent; if (parent == null || (parent._flags & UIElement.Flags.MeasureInProgress) != UIElement.Flags.None) { return; } parent.OnChildDesiredSizeChanged(this); } }