/// <summary> /// When overridden in a derived class, measures the size in layout /// required for child elements and determines a size for the System.Windows.FrameworkElement-derived class. /// </summary> /// <param name="availableSize">The available size that this element can give to child elements. Infinity can be specified as a value /// to indicate that the element will size to whatever content is available.</param> /// <returns>The size that this element determines it needs during layout, based on its calculations of child element sizes.</returns> protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize) { double totalHeight = 0; double maxWidth = 0; if (!double.IsPositiveInfinity(availableSize.Width)) { maxWidth = availableSize.Width; } List <UIElement> nonItemsElements = new List <UIElement>(); foreach (object child in InternalChildren) { MenuItem item = child as MenuItem; if ((item != null) && (item.Visibility != Visibility.Collapsed)) { item.Measure(availableSize); totalHeight += item.DesiredSize.Height; maxWidth = Math.Max(maxWidth, item.DesiredSize.Width); } else { Separator separator = child as Separator; if ((separator != null) && (separator.Visibility != Visibility.Collapsed)) { separator.Measure(availableSize); totalHeight += separator.DesiredSize.Height; maxWidth = Math.Max(maxWidth, separator.DesiredSize.Width); } else { UIElement uiElement = child as UIElement; if (uiElement != null) { nonItemsElements.Add(uiElement); } } } } if ((!double.IsPositiveInfinity(availableSize.Height))) { if (totalHeight < availableSize.Height) { double deltaHeight = (availableSize.Height - totalHeight) / nonItemsElements.Count; foreach (FrameworkElement item in nonItemsElements) { if (item.Visibility != Visibility.Collapsed) { item.Measure(new Size(availableSize.Width, deltaHeight)); maxWidth = Math.Max(maxWidth, Math.Max(item.DesiredSize.Width, (item).MinWidth)); totalHeight += Math.Max(item.DesiredSize.Height, (item).MinHeight); } } } else { foreach (FrameworkElement item in nonItemsElements) { if (item.Visibility != Visibility.Collapsed) { item.Measure(new Size()); maxWidth = Math.Max(maxWidth, Math.Max(item.DesiredSize.Width, item.MinWidth)); totalHeight += Math.Max(item.DesiredSize.Height, item.MinHeight); } } } } else { foreach (FrameworkElement item in nonItemsElements) { if (item.Visibility != Visibility.Collapsed) { item.Measure(availableSize); maxWidth = Math.Max(maxWidth, Math.Max(item.DesiredSize.Width, item.MinWidth)); totalHeight += Math.Max(item.DesiredSize.Height, item.MinHeight); } } } if (maxWidth < ResizeMinWidth) { maxWidth = ResizeMinWidth; } if (maxWidth > availableSize.Width) { maxWidth = availableSize.Width; } if (totalHeight < ResizeMinHeight) { totalHeight = ResizeMinHeight; } return(new Size(maxWidth, totalHeight)); }
private static void LayoutPage(ref List <ScrabbleSolution> .Enumerator it, FixedPage page, double?fontSize) { double marginX = 48; double marginY = 48; var sz = new Size(8.5 * 96 - 2 * marginX, 11 * 96 - 2 * marginY); // This is how we know we are done. // No more pages to layout if there // aren't any more solutions to show if (it.Current == null) { return; } //Do Page Header var headerTextBlock = new TextBlock { Text = "Scrabble Generator Solutions", FontSize = 25 }; headerTextBlock.Measure(sz); FixedPage.SetLeft(headerTextBlock, sz.Width / 2 - headerTextBlock.DesiredSize.Width / 2); // Center the Header FixedPage.SetTop(headerTextBlock, 48); // Put it at 1/2 inch down page.Children.Add(headerTextBlock); var separator = new Separator { Width = sz.Width, Height = 5 }; separator.Measure(sz); FixedPage.SetLeft(separator, marginX); FixedPage.SetTop(separator, marginY + headerTextBlock.DesiredSize.Height); page.Children.Add(separator); double x = marginX; double y = marginY + headerTextBlock.DesiredSize.Height + separator.DesiredSize.Height; double largestY = 0; do { var ctl = new ScrabbleSolutionControl { ScrabbleSolution = it.Current, Margin = new Thickness(10), }; if (fontSize.HasValue) { ctl.FontSize = fontSize.Value; } ctl.Measure(sz); // Page starts with two controls (Heading & separator.. Count==2). // If we haven't placed a Scrabble Solution (i.e Count==2), and the current // solution is too damn big to fit, lets keep shrinking the fontsize // by one until the solution fits! Yes, it will be one solution per page, // but the good news is that we will manage to print every solution for // the user, as close to as big as they wanted as possible. if (page.Children.Count == 2) { var newFontSize = ctl.FontSize; while (ctl.DesiredSize.Width > sz.Width - 2 * marginX || ctl.DesiredSize.Height > sz.Height - marginY) { ctl.FontSize = newFontSize--; ctl.Measure(sz); } } // When we run out of X space, we move down and start over in the x direction if (x + ctl.DesiredSize.Width > page.Width - 2 * marginX) { x = marginX; y += largestY; largestY = 0; } // When we run out of Y space, the page is full. if (y + ctl.DesiredSize.Height > page.Height - marginY) { break; } FixedPage.SetLeft(ctl, x); FixedPage.SetTop(ctl, y); page.Children.Add(ctl); x += ctl.DesiredSize.Width; largestY = Math.Max(largestY, ctl.DesiredSize.Height); }while(it.MoveNext() == true); }