public class WrapPanel : Panel { public Orientation Orientation { get { return (Orientation)GetValue(OrientationProperty); } set { SetValue(OrientationProperty, value); } } public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(WrapPanel), null); public WrapPanel() { // default orientation Orientation = Orientation.Horizontal; } protected override Size MeasureOverride(Size availableSize) { Point point = new Point(0, 0); int i = 0; if (Orientation == Orientation.Horizontal) { double largestSubHeight = 0.0; double finalHeight = 0.0; foreach (UIElement child in Children) { child.Measure(new Size(availableSize.Width, availableSize.Height)); if (child.DesiredSize.Height > largestSubHeight) largestSubHeight = child.DesiredSize.Height; point.X = point.X + child.DesiredSize.Width; if ((i + 1) < Children.Count) { if ((point.X + Children[i + 1].DesiredSize.Width) > availableSize.Width) { point.X = 0; point.Y = point.Y + largestSubHeight; finalHeight += largestSubHeight; largestSubHeight = 0.0; } } i++; } return new Size(ActualWidth, finalHeight); } else { double largestSubWidth = 0.0; double finalWidth = 0.0; foreach (UIElement child in Children) { child.Measure(new Size(availableSize.Width, availableSize.Height)); if (child.DesiredSize.Width > largestSubWidth) { largestSubWidth = child.DesiredSize.Width; } point.Y = point.Y + child.DesiredSize.Height; if ((i + 1) < Children.Count) { if ((point.Y + Children[i + 1].DesiredSize.Height) > availableSize.Height) { point.Y = 0; point.X = point.X + largestSubWidth; finalWidth += largestSubWidth; largestSubWidth = 0.0; } } i++; } return new Size(finalWidth, ActualHeight); } } protected override Size ArrangeOverride(Size finalSize) { Point point = new Point(0, 0); int i = 0; if (Orientation == Orientation.Horizontal) { double largestSubHeight = 0.0; double finalHeight = 0.0; foreach (UIElement child in Children) { child.Arrange(new Rect(point, new Point(point.X + child.DesiredSize.Width, point.Y + child.DesiredSize.Height))); if (child.DesiredSize.Height > largestSubHeight) largestSubHeight = child.DesiredSize.Height; point.X = point.X + child.DesiredSize.Width; if ((i + 1) < Children.Count) { if ((point.X + Children[i + 1].DesiredSize.Width) > finalSize.Width) { point.X = 0; point.Y = point.Y + largestSubHeight; finalHeight += largestSubHeight; largestSubHeight = 0.0; } } i++; } return Size.Empty; } else { double largestSubWidth = 0.0; double finalWidth = 0.0; foreach (UIElement child in Children) { child.Arrange(new Rect(point, new Point(point.X + child.DesiredSize.Width, point.Y + child.DesiredSize.Height))); if (child.DesiredSize.Width > largestSubWidth) { largestSubWidth = child.DesiredSize.Width; } point.Y = point.Y + child.DesiredSize.Height; if ((i + 1) < Children.Count) { if ((point.Y + Children[i + 1].DesiredSize.Height) > finalSize.Height) { point.Y = 0; point.X = point.X + largestSubWidth; finalWidth += largestSubWidth; largestSubWidth = 0.0; } } i++; } } return base.ArrangeOverride(finalSize); } }