/// <summary> /// Arrange a sequence of elements in a single line. /// </summary> /// <param name="lineStart"> /// Index of the first element in the sequence to arrange. /// </param> /// <param name="lineEnd"> /// Index of the last element in the sequence to arrange. /// </param> /// <param name="directDelta"> /// Optional fixed growth in the primary direction. /// </param> /// <param name="indirectOffset"> /// Offset of the line in the indirect direction. /// </param> /// <param name="indirectGrowth"> /// Shared indirect growth of the elements on this line. /// </param> /// <param name="maxDirect"> /// MaxSize of WrapPanel to be used in right to left orentation scenarios /// </param> private void ArrangeLine(int lineStart, int lineEnd, double?directDelta, double indirectOffset, double indirectGrowth // Added by lepipele , double maxDirect) { Orientation o = Orientation; bool isHorizontal = o == Orientation.Horizontal; FlowDirection f = FlowDirection; bool isLeftToRight = f == FlowDirection.LeftToRight; double directOffset = 0.0; if (!isLeftToRight) { directOffset = maxDirect; } UIElementCollection children = Children; for (int index = lineStart; index < lineEnd; index++) { // Get the size of the element UIElement element = children[index]; OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height double directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Arrange the element Rect bounds = Rect.Empty; if (isLeftToRight) { bounds = isHorizontal ? new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) : new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth); directOffset += directGrowth; } else { bounds = isHorizontal ? new Rect(directOffset - directGrowth, indirectOffset, directGrowth, indirectGrowth) : new Rect(indirectOffset, directOffset - directGrowth, indirectGrowth, directGrowth); directOffset -= directGrowth; } element.Arrange(bounds); } }
/// <summary> /// Arrange a sequence of elements in a single line. /// </summary> /// <param name="lineStart"> /// Index of the first element in the sequence to arrange. /// </param> /// <param name="lineEnd"> /// Index of the last element in the sequence to arrange. /// </param> /// <param name="directDelta"> /// Optional fixed growth in the primary direction. /// </param> /// <param name="indirectOffset"> /// Offset of the line in the indirect direction. /// </param> /// <param name="indirectGrowth"> /// Shared indirect growth of the elements on this line. /// </param> private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double indirectOffset, double indirectGrowth) { double directOffset = 0.0; Orientation o = Orientation; bool isHorizontal = o == Orientation.Horizontal; UIElementCollection children = Children; for (int index = lineStart; index < lineEnd; index++) { // Get the size of the element UIElement element = children[index]; OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height double directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Arrange the element Rect bounds = isHorizontal ? new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) : new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth); element.Arrange(bounds); directOffset += directGrowth; } }
/// <summary> /// Arranges and sizes the /// <see cref="T:System.Windows.Controls.WrapPanel" /> control and its /// child elements. /// </summary> /// <param name="finalSize"> /// The area within the parent that the /// <see cref="T:System.Windows.Controls.WrapPanel" /> should use /// arrange itself and its children. /// </param> /// <returns> /// The actual size used by the /// <see cref="T:System.Windows.Controls.WrapPanel" />. /// </returns> protected override Size ArrangeOverride(Size finalSize) { // Variables tracking the size of the current line, and the maximum // size available to fill. Note that the line might represent a row // or a column depending on the orientation. Orientation o = Orientation; OrientedSize lineSize = new OrientedSize(o); OrientedSize maximumSize = new OrientedSize(o, finalSize.Width, finalSize.Height); // Determine the constraints for individual items double itemWidth = ItemWidth; double itemHeight = ItemHeight; bool hasFixedWidth = !itemWidth.IsNaN(); bool hasFixedHeight = !itemHeight.IsNaN(); double indirectOffset = 0; double? directDelta = (o == Orientation.Horizontal) ? (hasFixedWidth ? (double?)itemWidth : null) : (hasFixedHeight ? (double?)itemHeight : null); // Measure each of the Children. We will process the elements one // line at a time, just like during measure, but we will wait until // we've completed an entire line of elements before arranging them. // The lineStart and lineEnd variables track the size of the // currently arranged line. UIElementCollection children = Children; int count = children.Count; int lineStart = 0; for (int lineEnd = 0; lineEnd < count; lineEnd++) { UIElement element = children[lineEnd]; // Get the size of the element OrientedSize elementSize = new OrientedSize( o, hasFixedWidth ? itemWidth : element.DesiredSize.Width, hasFixedHeight ? itemHeight : element.DesiredSize.Height); // If this element falls of the edge of the line if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct)) { // Then we just completed a line and we should arrange it ArrangeLine(lineStart, lineEnd, directDelta, indirectOffset, lineSize.Indirect); // Move the current element to a new line indirectOffset += lineSize.Indirect; lineSize = elementSize; // If the current element is larger than the maximum size if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct)) { // Arrange the element as a single line ArrangeLine(lineEnd, ++lineEnd, directDelta, indirectOffset, elementSize.Indirect); // Move to a new line indirectOffset += lineSize.Indirect; lineSize = new OrientedSize(o); } // Advance the start index to a new line after arranging lineStart = lineEnd; } else { // Otherwise just add the element to the end of the line lineSize.Direct += elementSize.Direct; lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect); } } // Arrange any elements on the last line if (lineStart < count) { ArrangeLine(lineStart, count, directDelta, indirectOffset, lineSize.Indirect); } return finalSize; }
protected override Size MeasureOverride(Size constraint) { // Variables tracking the size of the current line, the total size // measured so far, and the maximum size available to fill. Note // that the line might represent a row or a column depending on the // orientation. Orientation o = Orientation; OrientedSize lineSize = new OrientedSize(o); OrientedSize totalSize = new OrientedSize(o); OrientedSize maximumSize = new OrientedSize(o, constraint.Width, constraint.Height); // Determine the constraints for individual items double itemWidth = ItemWidth; double itemHeight = ItemHeight; bool hasFixedWidth = !itemWidth.IsNaN(); bool hasFixedHeight = !itemHeight.IsNaN(); Size itemSize = new Size( hasFixedWidth ? itemWidth : constraint.Width, hasFixedHeight ? itemHeight : constraint.Height); // Measure each of the Children foreach (UIElement element in Children) { // Determine the size of the element element.Measure(itemSize); OrientedSize elementSize = new OrientedSize( o, hasFixedWidth ? itemWidth : element.DesiredSize.Width, hasFixedHeight ? itemHeight : element.DesiredSize.Height); // If this element falls of the edge of the line if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct)) { // Update the total size with the direct and indirect growth // for the current line totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct); totalSize.Indirect += lineSize.Indirect; // Move the element to a new line lineSize = elementSize; // If the current element is larger than the maximum size, // place it on a line by itself if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct)) { // Update the total size for the line occupied by this // single element totalSize.Direct = Math.Max(elementSize.Direct, totalSize.Direct); totalSize.Indirect += elementSize.Indirect; // Move to a new line lineSize = new OrientedSize(o); } } else { // Otherwise just add the element to the end of the line lineSize.Direct += elementSize.Direct; lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect); } } // Update the total size with the elements on the last line totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct); totalSize.Indirect += lineSize.Indirect; // Return the total size required as an un-oriented quantity return new Size(totalSize.Width, totalSize.Height); }
/// <summary> /// Arranges and sizes the /// <see cref="T:System.Windows.Controls.WrapPanel" /> control and its /// child elements. /// </summary> /// <param name="finalSize"> /// The area within the parent that the /// <see cref="T:System.Windows.Controls.WrapPanel" /> should use /// arrange itself and its children. /// </param> /// <returns> /// The actual size used by the /// <see cref="T:System.Windows.Controls.WrapPanel" />. /// </returns> protected override Size ArrangeOverride(Size finalSize) { // Variables tracking the size of the current line, and the maximum // size available to fill. Note that the line might represent a row // or a column depending on the orientation. Orientation o = Orientation; OrientedSize lineSize = new OrientedSize(o); OrientedSize maximumSize = new OrientedSize(o, finalSize.Width, finalSize.Height); // Determine the constraints for individual items double itemWidth = ItemWidth; double itemHeight = ItemHeight; bool hasFixedWidth = !itemWidth.IsNaN(); bool hasFixedHeight = !itemHeight.IsNaN(); double indirectOffset = 0; double?directDelta = (o == Orientation.Horizontal) ? (hasFixedWidth ? (double?)itemWidth : null) : (hasFixedHeight ? (double?)itemHeight : null); // Measure each of the Children. We will process the elements one // line at a time, just like during measure, but we will wait until // we've completed an entire line of elements before arranging them. // The lineStart and lineEnd variables track the size of the // currently arranged line. UIElementCollection children = Children; int count = children.Count; int lineStart = 0; for (int lineEnd = 0; lineEnd < count; lineEnd++) { UIElement element = children[lineEnd]; // Get the size of the element OrientedSize elementSize = new OrientedSize( o, hasFixedWidth ? itemWidth : element.DesiredSize.Width, hasFixedHeight ? itemHeight : element.DesiredSize.Height); // If this element falls of the edge of the line if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct)) { // Then we just completed a line and we should arrange it ArrangeLine(lineStart, lineEnd, directDelta, indirectOffset, lineSize.Indirect); // Move the current element to a new line indirectOffset += lineSize.Indirect; lineSize = elementSize; // If the current element is larger than the maximum size if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct)) { // Arrange the element as a single line ArrangeLine(lineEnd, ++lineEnd, directDelta, indirectOffset, elementSize.Indirect); // Move to a new line indirectOffset += lineSize.Indirect; lineSize = new OrientedSize(o); } // Advance the start index to a new line after arranging lineStart = lineEnd; } else { // Otherwise just add the element to the end of the line lineSize.Direct += elementSize.Direct; lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect); } } // Arrange any elements on the last line if (lineStart < count) { ArrangeLine(lineStart, count, directDelta, indirectOffset, lineSize.Indirect); } return(finalSize); }
protected override Size MeasureOverride(Size constraint) { // Variables tracking the size of the current line, the total size // measured so far, and the maximum size available to fill. Note // that the line might represent a row or a column depending on the // orientation. Orientation o = Orientation; OrientedSize lineSize = new OrientedSize(o); OrientedSize totalSize = new OrientedSize(o); OrientedSize maximumSize = new OrientedSize(o, constraint.Width, constraint.Height); // Determine the constraints for individual items double itemWidth = ItemWidth; double itemHeight = ItemHeight; bool hasFixedWidth = !itemWidth.IsNaN(); bool hasFixedHeight = !itemHeight.IsNaN(); Size itemSize = new Size( hasFixedWidth ? itemWidth : constraint.Width, hasFixedHeight ? itemHeight : constraint.Height); // Measure each of the Children foreach (UIElement element in Children) { // Determine the size of the element element.Measure(itemSize); OrientedSize elementSize = new OrientedSize( o, hasFixedWidth ? itemWidth : element.DesiredSize.Width, hasFixedHeight ? itemHeight : element.DesiredSize.Height); // If this element falls of the edge of the line if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct)) { // Update the total size with the direct and indirect growth // for the current line totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct); totalSize.Indirect += lineSize.Indirect; // Move the element to a new line lineSize = elementSize; // If the current element is larger than the maximum size, // place it on a line by itself if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct)) { // Update the total size for the line occupied by this // single element totalSize.Direct = Math.Max(elementSize.Direct, totalSize.Direct); totalSize.Indirect += elementSize.Indirect; // Move to a new line lineSize = new OrientedSize(o); } } else { // Otherwise just add the element to the end of the line lineSize.Direct += elementSize.Direct; lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect); } } // Update the total size with the elements on the last line totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct); totalSize.Indirect += lineSize.Indirect; // Return the total size required as an un-oriented quantity return(new Size(totalSize.Width, totalSize.Height)); }
/// <summary> /// Arrange a sequence of elements in a single line. /// </summary> /// <param name="lineStart"> /// Index of the first element in the sequence to arrange. /// </param> /// <param name="lineEnd"> /// Index of the last+1 element in the sequence to arrange. /// </param> /// <param name="directDelta"> /// Optional fixed growth in the primary direction. /// </param> /// <param name="directMaximum"> /// Maximum length in the direct direction. /// </param> /// <param name="indirectOffset"> /// Offset of the line in the indirect direction. /// </param> /// <param name="indirectGrowth"> /// Shared indirect growth of the elements on this line. /// </param> private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double directMaximum, double indirectOffset, double indirectGrowth) { Orientation o = Orientation; bool isHorizontal = o == Orientation.Horizontal; UIElementCollection children = Children; double directLength = 0.0; double itemCount = 0.0; double itemLength = isHorizontal ? ItemWidth : ItemHeight; if (AlignLastItems && !itemLength.IsNaN()) { // Length is easy to calculate in this case itemCount = Math.Floor(directMaximum / itemLength); directLength = itemCount * itemLength; } else { // Make first pass to calculate the slack space itemCount = lineEnd - lineStart; for (int index = lineStart; index < lineEnd; index++) { // Get the size of the element UIElement element = children[index]; OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height double directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Update total length directLength += directGrowth; } } // Determine slack double directSlack = directMaximum - directLength; double directSlackSlice = directSlack / (itemCount + 1.0); double directOffset = directSlackSlice; // Make second pass to arrange items for (int index = lineStart; index < lineEnd; index++) { // Get the size of the element UIElement element = children[index]; OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height double directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Arrange the element Rect bounds = isHorizontal ? new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) : new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth); element.Arrange(bounds); // Update offset for next time directOffset += directGrowth + directSlackSlice; } }
/// <summary> /// Arrange a sequence of elements in a single line. /// </summary> /// <param name="lineStart"> /// Index of the first element in the sequence to arrange. /// </param> /// <param name="lineEnd"> /// Index of the last element in the sequence to arrange. /// </param> /// <param name="directDelta"> /// Optional fixed growth in the primary direction. /// </param> /// <param name="indirectOffset"> /// Offset of the line in the indirect direction. /// </param> /// <param name="indirectGrowth"> /// Shared indirect growth of the elements on this line. /// </param> /// <param name="maxDirect"> /// MaxSize of WrapPanel to be used in right to left orentation scenarios /// </param> private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double indirectOffset, double indirectGrowth // Added by lepipele , double maxDirect) { Orientation o = Orientation; bool isHorizontal = o == Orientation.Horizontal; FlowDirection f = FlowDirection; bool isLeftToRight = f == FlowDirection.LeftToRight; double directOffset = 0.0; if (!isLeftToRight) { directOffset = maxDirect; } UIElementCollection children = Children; for (int index = lineStart; index < lineEnd; index++) { // Get the size of the element UIElement element = children[index]; OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height double directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Arrange the element Rect bounds = Rect.Empty; if (isLeftToRight) { bounds = isHorizontal ? new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) : new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth); directOffset += directGrowth; } else { bounds = isHorizontal ? new Rect(directOffset - directGrowth, indirectOffset, directGrowth, indirectGrowth) : new Rect(indirectOffset, directOffset - directGrowth, indirectGrowth, directGrowth); directOffset -= directGrowth; } element.Arrange(bounds); } }
/// <summary> /// Arrange a sequence of elements in a single line. /// </summary> /// <param name="lineStart"> /// Index of the first element in the sequence to arrange. /// </param> /// <param name="lineEnd"> /// Index of the last+1 element in the sequence to arrange. /// </param> /// <param name="directDelta"> /// Optional fixed growth in the primary direction. /// </param> /// <param name="directMaximum"> /// Maximum length in the direct direction. /// </param> /// <param name="indirectOffset"> /// Offset of the line in the indirect direction. /// </param> /// <param name="indirectGrowth"> /// Shared indirect growth of the elements on this line. /// </param> private void ArrangeLine(int lineStart, int lineEnd, double?directDelta, double directMaximum, double indirectOffset, double indirectGrowth) { Orientation o = Orientation; bool isHorizontal = o == Orientation.Horizontal; UIElementCollection children = Children; double directLength = 0.0; double itemCount = 0.0; double itemLength = isHorizontal ? ItemWidth : ItemHeight; if (AlignLastItems && !itemLength.IsNaN()) { // Length is easy to calculate in this case itemCount = Math.Floor(directMaximum / itemLength); directLength = itemCount * itemLength; } else { // Make first pass to calculate the slack space itemCount = lineEnd - lineStart; for (int index = lineStart; index < lineEnd; index++) { // Get the size of the element UIElement element = children[index]; OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height double directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Update total length directLength += directGrowth; } } // Determine slack double directSlack = directMaximum - directLength; double directSlackSlice = directSlack / (itemCount + 1.0); double directOffset = directSlackSlice; // Make second pass to arrange items for (int index = lineStart; index < lineEnd; index++) { // Get the size of the element UIElement element = children[index]; OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height double directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Arrange the element Rect bounds = isHorizontal ? new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) : new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth); element.Arrange(bounds); // Update offset for next time directOffset += directGrowth + directSlackSlice; } }
/// <summary> /// Arrange a sequence of elements in a single line. /// </summary> /// <param name="lineStart"> /// Index of the first element in the sequence to arrange. /// </param> /// <param name="lineEnd"> /// Index of the last element in the sequence to arrange. /// </param> /// <param name="directDelta"> /// Optional fixed growth in the primary direction. /// </param> /// <param name="colWidth"> /// Offset of the line in the indirect direction. /// </param> /// <param name="colCount"> /// Shared indirect growth of the elements on this line. /// </param> private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double colWidth, int colCount) { var directOffset = 0.0; var o = Orientation; var isHorizontal = o == Orientation.Horizontal; var offset = colCount * colWidth; var children = Children; for (var index = lineStart; index < lineEnd; index++) { if (index >= children.Count) continue; // Get the size of the element var element = children[index]; var elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height); // Determine if we should use the element's desired size or the // fixed item width or height var directGrowth = directDelta != null ? directDelta.Value : elementSize.Direct; // Arrange the element var bounds = isHorizontal ? new Rect(directOffset, offset, directGrowth, colWidth) : new Rect(offset, directOffset, colWidth, directGrowth); element.Arrange(bounds); directOffset += directGrowth; } }
/// <summary> /// Arranges and sizes the /// <see cref="DynamicallySizedWrapPanel" /> control and its /// child elements. /// </summary> /// <param name="finalSize"> /// The area within the parent that the /// <see cref="DynamicallySizedWrapPanel" /> should use /// arrange itself and its children. /// </param> /// <returns> /// The actual size used by the /// <see cref="DynamicallySizedWrapPanel" />. /// </returns> protected override Size ArrangeOverride(Size finalSize) { #region Initialize Variables // Variables tracking the size of the current line, and the maximum // size available to fill. Note that the line might represent a row // or a column depending on the orientation. var o = Orientation; var lineSize = new OrientedSize(o); var maximumSize = new OrientedSize(o, finalSize.Width, finalSize.Height); var numCols = NumberOfColumns; // Determine the constraints for individual items var itemWidth = ItemWidth; var itemHeight = ItemHeight; var hasFixedWidth = !itemWidth.IsNaN(); var hasFixedHeight = !itemHeight.IsNaN(); var indirectOffset = 0.0; var directDelta = (o == Orientation.Horizontal) ? (hasFixedWidth ? (double?)itemWidth : null) : (hasFixedHeight ? (double?)itemHeight : null); // Measure each of the Children. We will process the elements one // line at a time, just like during measure, but we will wait until // we've completed an entire line of elements before arranging them. // The lineStart and lineEnd variables track the size of the // currently arranged line. var children = Children; var numberOfElements = children.Count; #endregion //TODO: Measure all of the children and save those numbers into an array var sizeArray = new int[(children.Where(c => c.DesiredSize.Height > 0)).Count()]; var count = 0; //Iterates through the children to find the height for each and saves them to an arrays foreach (var child in Children) { if ((int)child.DesiredSize.Height != 0) { sizeArray[count] = (int)child.DesiredSize.Height; count++; } } //TODO: Figure out mean and standard deviation for the set //Had to specify double for the division that occurs below var totalChildHeight = sizeArray.Sum(); double averageChildHeight = 0; if (sizeArray.Length > 0) averageChildHeight = sizeArray.Average(); #region Standard Deviation Calculator double totalVariance = 0; var lengthOfArray = sizeArray.Length; var dataAverage = averageChildHeight; totalVariance += sizeArray.Sum(childHeight => Math.Pow(childHeight - dataAverage, 2)); var stDev = lengthOfArray != 0 ? Math.Sqrt(totalVariance / lengthOfArray) : 0; #endregion //TODO: Put objects in each column until it surpasses any of the requirements //The average number of items each column should have var averageElementsPerColumn = numberOfElements / numCols; //Average height for a column var averageColumnHeight = totalChildHeight / numCols; var startOfColumnElementIndex = new int[numCols]; var endOfColumnElementIndex = new int[numCols]; startOfColumnElementIndex[0] = 0; //Set to negative 1 so that when the loop exits, the tracker will still be in the right position var positionTracker = -1; var maxHeight = 0; var tallestColumn = 0; for (var i = 0; i < numCols; i++) { var thisColHeight = 0; startOfColumnElementIndex[i] = (positionTracker + 1); var minHeightForColumn = (averageColumnHeight - (.5 * stDev)); while (thisColHeight < minHeightForColumn && positionTracker < (children.Count - 1)) //(c => c.DesiredSize.Height > 0) { positionTracker++; thisColHeight += (int)children[positionTracker].DesiredSize.Height; } //if (thisColHeight > maxHeightForColumn || startOfColumnElementIndex[i] == positionTracker) // positionTracker--; endOfColumnElementIndex[i] = positionTracker; if (i == (numCols - 1)) { endOfColumnElementIndex[i] = positionTracker - 1; //thisColHeight -= (int)children[positionTracker].DesiredSize.Height; } if (thisColHeight > maxHeight) { tallestColumn = i; maxHeight = thisColHeight; } } //TODO: Print to the screen var colWidth = finalSize.Width / numCols; #region Print Elements to the screen var tallestChild = 0; if (children.Count(c => c.DesiredSize.Height > 0) == numCols) { var i = 0; for (var counter = 0; counter < children.Count; counter++) { if (children[counter].DesiredSize.Height > 0) { startOfColumnElementIndex[i] = counter; endOfColumnElementIndex[i] = counter; i++; if (children[counter].DesiredSize.Height > tallestChild) { tallestChild = (int) children[counter].DesiredSize.Height; tallestColumn = i - 1; } } } } var lineStart = 0; var colCount = 0; var firstCol = true; //Iterate through each column for (var colIndex = 0; colIndex < numCols; colIndex++) { //Iterate through each element in the column for (var elementIndexToPrint = startOfColumnElementIndex[colIndex]; elementIndexToPrint <= endOfColumnElementIndex[colIndex]; elementIndexToPrint++) { var element = children[elementIndexToPrint]; if (Math.Abs(element.DesiredSize.Height - 0.0) <= 0) continue; // Get the size of the element var elementSize = new OrientedSize( o, hasFixedWidth ? itemWidth : element.DesiredSize.Width, hasFixedHeight ? itemHeight : element.DesiredSize.Height); // If this element falls off the edge of the line if (elementIndexToPrint == endOfColumnElementIndex[colIndex]) { #region use this to print things // Then we just completed a line and we should arrange it ArrangeLine(lineStart, ++elementIndexToPrint, directDelta, colWidth, colCount); colCount++; // Advance the start index to a new line after arranging lineStart = elementIndexToPrint; if (firstCol) { lineSize.Indirect = elementSize.Indirect; } firstCol = false; // Move the current element to a new line indirectOffset += lineSize.Indirect; lineSize = elementSize; #endregion lineSize.Indirect = 0; continue; } // Otherwise just add the element to the end of the line lineSize.Direct += elementSize.Direct; lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect); } } #endregion var tallestHeight = 0; for (var i = startOfColumnElementIndex[tallestColumn]; i <= endOfColumnElementIndex[tallestColumn]; i++) { tallestHeight += (int)children[i].DesiredSize.Height; } var test = maxHeight; return new Size(finalSize.Width, tallestHeight); }
protected override Size MeasureOverride(Size constraint) { // Variables tracking the size of the current line, the total size // measured so far, and the maximum size available to fill. Note // that the line might represent a row or a column depending on the // orientation. var o = Orientation; //var lineSize = new OrientedSize(o); var totalSize = new OrientedSize(o); //var maximumSize = new OrientedSize(o, constraint.Width, constraint.Height); // Determine the constraints for individual items var itemWidth = ItemWidth; var itemHeight = ItemHeight; var hasFixedWidth = !itemWidth.IsNaN(); var hasFixedHeight = !itemHeight.IsNaN(); var itemSize = new Size( hasFixedWidth ? itemWidth : constraint.Width, hasFixedHeight ? itemHeight : constraint.Height); var numCols = NumberOfColumns; var children = Children; var numberOfElements = children.Count; // Measure each of the Children foreach (var element in Children) { // Determine the size of the element element.Measure(itemSize); } #region Copied From ArrangeOverride var startOfColumnElementIndex = new int[numCols]; var endOfColumnElementIndex = new int[numCols]; var tallestHeight = 0; //if (children.Count(c => c.DesiredSize.Height > 0) == numCols) //{ // var i = 0; // for (var counter = 0; counter < children.Count; counter++) // { // if (children[counter].DesiredSize.Height > 0) // { // startOfColumnElementIndex[i] = counter; // endOfColumnElementIndex[i] = counter; // i++; // } // } // foreach (var child in children.Where(child => child.DesiredSize.Height > tallestHeight)) // tallestHeight = (int)child.DesiredSize.Height; // // Return the total size required as an un-oriented quantity // return new Size(totalSize.Width, tallestHeight); //} var sizeArray = new int[(children.Where(c => c.DesiredSize.Height > 0)).Count()]; var count = 0; //Iterates through the children to find the height for each and saves them to an arrays foreach (var child in Children) { if ((int)child.DesiredSize.Height != 0) { sizeArray[count] = (int)child.DesiredSize.Height; count++; } } //TODO: Figure out mean and standard deviation for the set //Had to specify double for the division that occurs below var totalChildHeight = sizeArray.Sum(); double averageChildHeight = 0; if (sizeArray.Length > 0) averageChildHeight = sizeArray.Average(); #region Standard Deviation Calculator double totalVariance = 0; var lengthOfArray = sizeArray.Length; var dataAverage = averageChildHeight; totalVariance += sizeArray.Sum(childHeight => Math.Pow(childHeight - dataAverage, 2)); var stDev = lengthOfArray != 0 ? Math.Sqrt(totalVariance / lengthOfArray) : 0; #endregion //TODO: Put objects in each column until it surpasses any of the requirements //The average number of items each column should have var averageElementsPerColumn = numberOfElements / numCols; //Average height for a column var averageColumnHeight = totalChildHeight / numCols; startOfColumnElementIndex[0] = 0; //Set to negative 1 so that when the loop exits, the tracker will still be in the right position var positionTracker = -1; var maxHeight = 0; var tallestColumn = 0; for (var i = 0; i < numCols; i++) { var thisColHeight = 0; startOfColumnElementIndex[i] = (positionTracker + 1); var minHeightForColumn = (averageColumnHeight - (.5 * stDev)); while (thisColHeight < minHeightForColumn && positionTracker < (children.Count - 1)) //(c => c.DesiredSize.Height > 0) { positionTracker++; thisColHeight += (int)children[positionTracker].DesiredSize.Height; } //if (thisColHeight > maxHeightForColumn || startOfColumnElementIndex[i] == positionTracker) // positionTracker--; endOfColumnElementIndex[i] = positionTracker; if (i == (numCols - 1)) { endOfColumnElementIndex[i] = positionTracker - 1; //thisColHeight -= (int)children[positionTracker].DesiredSize.Height; } if (thisColHeight > maxHeight) { tallestColumn = i; maxHeight = thisColHeight; } } #endregion for (var i = startOfColumnElementIndex[tallestColumn]; i <= endOfColumnElementIndex[tallestColumn]; i++) { tallestHeight += (int)children[i].DesiredSize.Height; } // Return the total size required as an un-oriented quantity return new Size(totalSize.Width, tallestHeight); }