Revision: 18763
Updated Code
at October 7, 2009 19:16 by ingebretsen
Updated Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows; namespace JustifyingWrapPanelTest { public class StretchWrapPanel : Panel { protected override Size MeasureOverride(Size availableSize) { double lineWidth = 0; double lineHeight = 0; double totalWidth = 0; double totalHeight = 0; Size asBigAsYouWant = new Size(double.PositiveInfinity, double.PositiveInfinity); foreach (UIElement element in this.Children) { element.Measure(asBigAsYouWant); Size itemSize = GetItemDesiredSize(element); // reset the line if we run out of room if ((this.Children[this.Children.Count - 1].Equals(element)) || (lineWidth + GetItemDesiredSize(this.Children[this.Children.IndexOf(element) + 1]).Width > availableSize.Width)) { if (lineWidth > totalWidth) totalWidth = lineWidth; lineWidth = 0; totalHeight += lineHeight; lineHeight = 0; } lineWidth += itemSize.Width; // take the tallest item in the line as our lineHeight if (itemSize.Height > lineHeight) lineHeight = itemSize.Height; } return new Size(availableSize.Width, totalHeight); } protected override Size ArrangeOverride(Size finalSize) { int lineCount = 0; double lineWidth = 0; double lineHeight = 0; double top = 0; double left = 0; double width = 0; double height = 0; double gap = 0; for (int u = 0; u <= this.Children.Count - 1; u++) { UIElement curr = this.Children[u]; Size currSize = GetItemDesiredSize(curr); lineCount++; lineWidth = lineWidth + currSize.Width; lineHeight = Math.Max(lineHeight, currSize.Height); bool isLast = this.Children[this.Children.Count - 1].Equals(curr); if (isLast || (lineWidth + GetItemDesiredSize(this.Children[u + 1]).Width) >= finalSize.Width) { gap = isLast ? gap : lineCount <= 1 ? 0 : (finalSize.Width - lineWidth) / (lineCount - 1); for (int i = (u - lineCount) + 1; i <= u; i++) { UIElement element = this.Children[i]; width = GetItemDesiredSize(element).Width; height = GetItemDesiredSize(element).Height; element.Arrange(new Rect(left, top, width, height)); left += (width + gap); } top += lineHeight; left = 0; // reset our line markers lineWidth = 0; lineHeight = 0; lineCount = 0; } } return finalSize; } private Size GetItemDesiredSize(UIElement element) { Size itemSize = new Size(); itemSize.Width = double.IsInfinity(element.DesiredSize.Width) ? 0 : element.DesiredSize.Width; itemSize.Height = double.IsInfinity(element.DesiredSize.Height) ? 0 : element.DesiredSize.Height; return itemSize; } } }
Revision: 18762
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at October 7, 2009 19:15 by ingebretsen
Initial Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows; namespace JustifyingWrapPanelTest { public class StretchWrapPanel : Panel { protected override Size MeasureOverride(Size availableSize) { double lineWidth = 0; double lineHeight = 0; double totalWidth = 0; double totalHeight = 0; Size asBigAsYouWant = new Size(double.PositiveInfinity, double.PositiveInfinity); foreach (UIElement element in this.Children) { element.Measure(asBigAsYouWant); Size itemSize = GetItemDesiredSize(element); // reset the line if we run out of room if ((this.Children[this.Children.Count - 1].Equals(element)) || (lineWidth + GetItemDesiredSize(this.Children[this.Children.IndexOf(element) + 1]).Width > availableSize.Width)) { if (lineWidth > totalWidth) totalWidth = lineWidth; lineWidth = 0; totalHeight += lineHeight; lineHeight = 0; } lineWidth += itemSize.Width; // take the tallest item in the line as our lineHeight if (itemSize.Height > lineHeight) lineHeight = itemSize.Height; } return new Size(availableSize.Width, totalHeight); } protected override Size ArrangeOverride(Size finalSize) { int lineCount = 0; double lineWidth = 0; double lineHeight = 0; double top = 0; double left = 0; double width = 0; double height = 0; double gap = 0; for (int u = 0; u <= this.Children.Count - 1; u++) { UIElement curr = this.Children[u]; Size currSize = GetItemDesiredSize(curr); lineCount++; lineWidth = lineWidth + currSize.Width; lineHeight = Math.Max(lineHeight, currSize.Height); bool isLast = this.Children[this.Children.Count - 1].Equals(curr); if (isLast || (lineWidth + GetItemDesiredSize(this.Children[u + 1]).Width) >= finalSize.Width) { gap = isLast ? gap : lineCount <= 1 ? 0 : (finalSize.Width - lineWidth) / (lineCount - 1); for (int i = (u - lineCount) + 1; i <= u; i++) { UIElement element = this.Children[i]; width = GetItemDesiredSize(element).Width; height = GetItemDesiredSize(element).Height; element.Arrange(new Rect(left, top, width, height)); left += (width + gap); } top += lineHeight; left = 0; // reset our line markers lineWidth = 0; lineHeight = 0; lineCount = 0; } //Size itemSize = GetItemDesiredSize(element); //lineWidth += itemSize.Width; //lineHeight = Math.Max(lineHeight, itemSize.Height); //if (this.Children[this.Children.Count- 1].Equals(element) || (lineWidth + this.Children[u+1].DesiredSize.Width) >= finalSize.Width) //{ // // process the line // left = 0; // //if (lineCount > 1) // { // double gap = (finalSize.Width - lineWidth) / (lineCount); // for (int i = startIndex; i < startIndex + lineCount; i++) // { // UIElement next = this.Children[i]; // width = next.DesiredSize.Width; // height = lineHeight; // next.Arrange(new Rect(left, top, width, height)); // left += (width + gap); // } // } // //else // //{ // // width = element.DesiredSize.Width; // // height = lineHeight; // // element.Arrange(new Rect(left, top, width, height)); // //} // // reset the line counts // top += lineHeight; // lineWidth = 0; // lineHeight = 0; // startIndex = startIndex + lineCount; // lineCount = 0; //} //else //{ // // TODO update line height // // TODO update the lineWidth //} //lineCount++; } return finalSize; } private Size GetItemDesiredSize(UIElement element) { Size itemSize = new Size(); itemSize.Width = double.IsInfinity(element.DesiredSize.Width) ? 0 : element.DesiredSize.Width; itemSize.Height = double.IsInfinity(element.DesiredSize.Height) ? 0 : element.DesiredSize.Height; return itemSize; } } }
Initial URL
Initial Description
This is a flowpanel that automatically justifies it's lines so that the elements are justified.
Initial Title
StrechFlowPanel
Initial Tags
Initial Language
C#