Posted By

ingebretsen on 10/07/09


Tagged

WPF Silverlight


Versions (?)

StrechFlowPanel


 / Published in: C#
 

This is a flowpanel that automatically justifies it's lines so that the elements are justified.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows.Controls;
  6. using System.Windows;
  7.  
  8. namespace JustifyingWrapPanelTest
  9. {
  10. public class StretchWrapPanel : Panel
  11. {
  12. protected override Size MeasureOverride(Size availableSize)
  13. {
  14. double lineWidth = 0;
  15. double lineHeight = 0;
  16. double totalWidth = 0;
  17. double totalHeight = 0;
  18.  
  19. Size asBigAsYouWant = new Size(double.PositiveInfinity, double.PositiveInfinity);
  20.  
  21. foreach (UIElement element in this.Children)
  22. {
  23. element.Measure(asBigAsYouWant);
  24. Size itemSize = GetItemDesiredSize(element);
  25.  
  26. // reset the line if we run out of room
  27. if ((this.Children[this.Children.Count - 1].Equals(element)) || (lineWidth + GetItemDesiredSize(this.Children[this.Children.IndexOf(element) + 1]).Width > availableSize.Width))
  28. {
  29. if (lineWidth > totalWidth) totalWidth = lineWidth;
  30. lineWidth = 0;
  31.  
  32. totalHeight += lineHeight;
  33. lineHeight = 0;
  34. }
  35.  
  36. lineWidth += itemSize.Width;
  37.  
  38. // take the tallest item in the line as our lineHeight
  39. if (itemSize.Height > lineHeight) lineHeight = itemSize.Height;
  40. }
  41.  
  42.  
  43. return new Size(availableSize.Width, totalHeight);
  44. }
  45.  
  46.  
  47. protected override Size ArrangeOverride(Size finalSize)
  48. {
  49. int lineCount = 0;
  50. double lineWidth = 0;
  51. double lineHeight = 0;
  52.  
  53. double top = 0;
  54. double left = 0;
  55. double width = 0;
  56. double height = 0;
  57. double gap = 0;
  58.  
  59. for (int u = 0; u <= this.Children.Count - 1; u++)
  60. {
  61. UIElement curr = this.Children[u];
  62. Size currSize = GetItemDesiredSize(curr);
  63. lineCount++;
  64.  
  65. lineWidth = lineWidth + currSize.Width;
  66. lineHeight = Math.Max(lineHeight, currSize.Height);
  67.  
  68. bool isLast = this.Children[this.Children.Count - 1].Equals(curr);
  69.  
  70. if (isLast || (lineWidth + GetItemDesiredSize(this.Children[u + 1]).Width) >= finalSize.Width)
  71. {
  72. gap = isLast ? gap : lineCount <= 1 ? 0 : (finalSize.Width - lineWidth) / (lineCount - 1);
  73. for (int i = (u - lineCount) + 1; i <= u; i++)
  74. {
  75. UIElement element = this.Children[i];
  76. width = GetItemDesiredSize(element).Width;
  77. height = GetItemDesiredSize(element).Height;
  78.  
  79. element.Arrange(new Rect(left, top, width, height));
  80.  
  81. left += (width + gap);
  82. }
  83.  
  84. top += lineHeight;
  85. left = 0;
  86.  
  87. // reset our line markers
  88. lineWidth = 0;
  89. lineHeight = 0;
  90. lineCount = 0;
  91. }
  92. }
  93.  
  94. return finalSize;
  95. }
  96.  
  97. private Size GetItemDesiredSize(UIElement element)
  98. {
  99. Size itemSize = new Size();
  100. itemSize.Width = double.IsInfinity(element.DesiredSize.Width) ? 0 : element.DesiredSize.Width;
  101. itemSize.Height = double.IsInfinity(element.DesiredSize.Height) ? 0 : element.DesiredSize.Height;
  102. return itemSize;
  103. }
  104.  
  105. }
  106. }

Report this snippet  

You need to login to post a comment.