protected override Size ArrangeOverride(Size arrangeBounds) { if (Orientation != Orientation.Horizontal) { throw new NotImplementedException("The WrapBreakPanel only supports horizontal orientation."); } Size currentLineSize = new Size(); double totalHeight = 0; // Examine all the elements in this panel. foreach (UIElement element in this.Children) { // Get the desired size of the element, but don't call Measure() again, // or that will trigger the measure layout pass and MeasureOverride()! Size desiredSize = element.DesiredSize; // Check if the element fits in the line, if given its desired size. if ((currentLineSize.Width + desiredSize.Width > arrangeBounds.Width) || (WrapBreakPanel.GetLineBreakBefore(element))) { // Switch to a new line because space has run out. totalHeight += currentLineSize.Height; currentLineSize = new Size(); } // Make sure the line is as tall as its tallest element. currentLineSize.Height = Math.Max(desiredSize.Height, currentLineSize.Height); // Place the element on the line, giving it its desired size. element.Arrange(new Rect(currentLineSize.Width, totalHeight, element.DesiredSize.Width, element.DesiredSize.Height)); // Move over for the next element. currentLineSize.Width += desiredSize.Width; } // Return the size this panel actually occupies. totalHeight += currentLineSize.Height; return(new Size(arrangeBounds.Width, totalHeight)); }
protected override Size MeasureOverride(Size constraint) { if (Orientation != Orientation.Horizontal) { throw new NotImplementedException("The WrapBreakPanel only supports horizontal orientation."); } Size currentLineSize = new Size(); Size panelSize = new Size(); // Examine all the elements in this panel. foreach (UIElement element in this.Children) { // Get the desired size of the element. element.Measure(constraint); Size desiredSize = element.DesiredSize; // Check if the element fits in the line, if given its desired size. if ((currentLineSize.Width + desiredSize.Width > constraint.Width) || (WrapBreakPanel.GetLineBreakBefore(element))) { // Switch to a new line because space has run out. panelSize.Height += currentLineSize.Height; panelSize.Width = Math.Max(currentLineSize.Width, panelSize.Width); currentLineSize = desiredSize; // If the element is too wide to fit using the maximum width of the line, // just give it a separate line. if (desiredSize.Width > constraint.Width) { // Make the width of the element the new desired width. panelSize.Width = Math.Max(desiredSize.Width, panelSize.Width); } } else { // Add the element to the current line. currentLineSize.Width += desiredSize.Width; // Make sure the line is as tall as its tallest element. currentLineSize.Height = Math.Max(desiredSize.Height, currentLineSize.Height); } } // Return the size required to fit all elements. // Ordinarily, this is the width of the constraint, and the height // required to fit all the elements. // However, if an element is wider than the width given to the panel, // the desired width will be the width of that line. panelSize.Width = Math.Max(currentLineSize.Width, panelSize.Width); panelSize.Height += currentLineSize.Height; return(panelSize); }