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#