protected virtual void FillPrefSizeList(List <PreferredSizeData> prefSizelist, Rectangle bounds) { // Split children in 2 lists: with own size and with AutoSizeMode == FitToAvailableSize // Only for children with own size will be called GetPreferredSize() List <RadElement> fitElementsList = new List <RadElement>(); int leftTopOffset = 0, rightBottomOffset = 0; this.maxIntegralHeight = 0; foreach (RadElement child in this.GetChildrenForLayout()) { if (child.IsFitInSize()) { fitElementsList.Add(child); } else { // The constructor of PreferredSizeData will call GetPreferredSize() PreferredSizeData prefSizedata = new PreferredSizeData(child, bounds); StripPosition pos = GetInvariantPosition(child.Alignment); if (pos == StripPosition.First) { leftTopOffset += GetInvariantLength(prefSizedata.PreferredSize, child.Margin); } else if (pos == StripPosition.Last) { rightBottomOffset += GetInvariantLength(prefSizedata.PreferredSize, child.Margin); } prefSizelist.Add(prefSizedata); this.maxIntegralWidth = Math.Max(this.maxIntegralWidth, prefSizedata.PreferredSize.Width); this.maxIntegralHeight = Math.Max(this.maxIntegralHeight, prefSizedata.PreferredSize.Height); } } // Calculate preferred size for "FitToAvailableSize" elements Rectangle proposedRect = CalcProposedBounds(bounds, prefSizelist, leftTopOffset, rightBottomOffset); // Call GetPreferredSize() for children that are with AutoSizeMode == FitToAvailableSize foreach (RadElement child in fitElementsList) { //prefSizelist.Add(new PreferredSizeData(child, proposedRect)); prefSizelist.Add(new PreferredSizeData(child, proposedRect.Size, this.forceFitToSizeElements)); } }
/// <summary> /// Performs layout changes based on the element given as a paramater. /// Sizes and places are determined by the concrete layout panel that is used. /// Since all layout panels update their layout automatically through events, /// this function is rarely used directly. /// </summary> /// <param name="affectedElement"></param> public override void PerformLayoutCore(RadElement affectedElement) { int nextLeftTop = 0, nextRightBottom = 0; Rectangle bounds = this.Bounds; bounds.Size = TelerikLayoutEngine.CheckSize(this.Size, this.MaxSize, this.MinSize); List <PreferredSizeData> prefSizelist = new List <PreferredSizeData>(); FillPrefSizeList(prefSizelist, bounds); if (!this.ShouldIgnoreChildSizes()) { bounds.Size = GetChildrenListSize(prefSizelist); } foreach (PreferredSizeData data in prefSizelist) { if (data.Element.Visibility != ElementVisibility.Collapsed) { StripPosition pos = GetInvariantPosition(data.Element.Alignment); switch (pos) { case StripPosition.First: SetElementBoundsAuto(bounds, data, nextLeftTop); nextLeftTop += GetInvariantLength(data.Element.BoundingRectangle.Size, data.Element.Margin); break; case StripPosition.Middle: SetElementBoundsAuto(bounds, data, 0); break; case StripPosition.Last: SetElementBoundsAuto(bounds, data, nextRightBottom); nextRightBottom -= GetInvariantLength(data.Element.BoundingRectangle.Size, data.Element.Margin); break; } } } }
/// <summary> /// arranges the children by a given criteria /// </summary> /// <param name="finalSize"></param> /// <returns></returns> protected override SizeF ArrangeOverride(SizeF finalSize) { PointF firstPositions = PointF.Empty; PointF lastPositions = PointF.Empty; if (this.Orientation == Orientation.Horizontal) { lastPositions.X = finalSize.Width; } if (this.Orientation == Orientation.Vertical) { lastPositions.Y = finalSize.Height; } SizeF nonStretchableSize = SizeF.Empty; List <RadElement> stretchOnChildren = new List <RadElement>(); List <RadElement> stretchOffChildren = new List <RadElement>(); List <RadElement> proportionedChildren = new List <RadElement>(); float availableWidth = finalSize.Width; float availableHeight = finalSize.Height; float proportionSum = 0; for (int i = 0; i < this.Children.Count; i++) { RadElement child = this.Children[i]; if (child.AutoSize == false) { continue; } if (child != null) { float childProportion = GetProportion(child); if (this.Orientation == Orientation.Horizontal) { if (child.StretchHorizontally) { stretchOnChildren.Add(child); } else { stretchOffChildren.Add(child); } } else { if (child.StretchVertically) { stretchOnChildren.Add(child); } else { stretchOffChildren.Add(child); } } if (childProportion != 0) { proportionedChildren.Add(child); } else { if (Orientation == Orientation.Horizontal) { availableWidth -= child.DesiredSize.Width; } else { availableHeight -= child.DesiredSize.Height; } } proportionSum += childProportion; } } if (proportionSum == 0) { availableWidth = finalSize.Width; availableHeight = finalSize.Height; } for (int i = 0; i < stretchOffChildren.Count; i++) { RadElement child = stretchOffChildren[i]; if (child.AutoSize == false) { continue; } SizeF childSize = SizeF.Empty; float childProportion = GetProportion(child); if (childProportion == 0) { childSize = child.DesiredSize; } if (this.Orientation == Orientation.Horizontal) { if (childProportion != 0) { childSize = new SizeF((availableWidth * childProportion) / proportionSum, availableHeight); } nonStretchableSize.Width += childSize.Width; //if (child.StretchVertically) childSize.Height = availableHeight; StripPosition stripPosition = (StripPosition)child.GetValue(StripPositionProperty); bool isFirst = ((stripPosition == StripPosition.First) ^ this.RightToLeft); if (isFirst) { child.Arrange(new RectangleF(firstPositions, childSize)); firstPositions.X += childSize.Width; } else { lastPositions.X -= childSize.Width; child.Arrange(new RectangleF(lastPositions, childSize)); } } else { if (childProportion != 0) { childSize = new SizeF(availableWidth, (availableHeight * childProportion) / proportionSum); } nonStretchableSize.Height += child.DesiredSize.Height; //if (child.StretchHorizontally) childSize.Width = availableWidth; StripPosition stripPosition = (StripPosition)child.GetValue(StripPositionProperty); switch (stripPosition) { case StripPosition.First: child.Arrange(new RectangleF(firstPositions, childSize)); firstPositions.Y += childSize.Height; break; case StripPosition.Last: lastPositions.Y -= childSize.Height; child.Arrange(new RectangleF(lastPositions, childSize)); break; } } } for (int i = 0; i < stretchOnChildren.Count; i++) { float x = 0; float y = 0; RadElement child = stretchOnChildren[i]; if (child.AutoSize == false) { continue; } SizeF childSize = SizeF.Empty; float childProportion = GetProportion(child); if (childProportion == 0) { childSize = child.DesiredSize; } if (this.Orientation == Orientation.Horizontal) { if (childProportion != 0) { childSize = new SizeF((availableWidth * childProportion) / proportionSum, availableHeight); } else { childSize.Width = availableWidth - nonStretchableSize.Width; } x = childSize.Width; //if (child.StretchVertically) childSize.Height = availableHeight; if (!this.RightToLeft) { child.Arrange(new RectangleF(firstPositions, childSize)); firstPositions.X += x; firstPositions.Y += y; } else { lastPositions.X -= x; lastPositions.Y -= y; child.Arrange(new RectangleF(lastPositions, childSize)); } } else { if (childProportion != 0) { childSize = new SizeF(availableWidth, (availableHeight * childProportion) / proportionSum); y = childSize.Height; } else { childSize.Height = availableHeight - nonStretchableSize.Height; //if (child.StretchHorizontally) childSize.Width = availableWidth; } child.Arrange(new RectangleF(firstPositions, childSize)); firstPositions.X += x; firstPositions.Y += y; } } return(finalSize); }