public ListDependencyProperties() { InitializeComponent(); DataContext = this; CopyProps = new ViewAction(execute: (a, o) => Clipboard.SetText(DependencyPropList)); var layout = new MetroTiles(); Title = layout.ToString(); DependencyProps = GetDependencyProperties(layout); }
private Size IterateChildren(Size availableSize, Action <UIElement, Rect> methodToCall) { try { var absoluteTop = ContentTopLeftPadding.Height; var top = absoluteTop; var left = ContentTopLeftPadding.Width; var heightUsed = top; var widthUsed = left; var horizontalSpacing = GetHorizontalTileSpacing(this); var verticalSpacing = GetVerticalTileSpacing(this); var horizontalGroupSpacing = GetHorizontalGroupSpacing(this); var tileWidthNormal = GetTileWidth(this); var tileHeight = GetTileHeight(this); var tileWidthDouble = tileWidthNormal * 2 + horizontalSpacing; var tileWidthTiny = (tileWidthNormal - horizontalSpacing) / 2; var groups = GetChildrenByGroup(); // We figure out whether we need to leave space for headers if (RenderHeaders) { _headers.Clear(); var titles = new List <string>(); var foundTitle = false; foreach (var groupKey in groups.Keys) { var group = groups[groupKey]; if (group.Count > 0) { var groupTitle = GetGroupTitleForObject(group[0]); titles.Add(groupTitle); if (!string.IsNullOrEmpty(groupTitle)) { foundTitle = true; } } else { titles.Add(string.Empty); } } if (foundTitle) { var maxHeaderHeight = 0d; foreach (var title in titles) { var header = new AutoHeaderTextRenderInfo { Text = title, FormattedText = new FormattedText(title, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(HeaderFontFamily, HeaderFontStyle, HeaderFontWeight, FontStretches.Normal), HeaderFontSize, HeaderForegroundBrush) }; maxHeaderHeight = Math.Max(header.FormattedText.Height, maxHeaderHeight); _headers.Add(header); } if (maxHeaderHeight > 0) { absoluteTop += maxHeaderHeight + HeaderSpacing; top += maxHeaderHeight + HeaderSpacing; heightUsed += maxHeaderHeight + HeaderSpacing; } } } var groupCount = -1; foreach (var group in groups.Values) { groupCount++; var groupWidth = tileWidthDouble; var groupLeft = left; var currentTinyCount = 0; var currentNormalCount = 0; var currentMaxColumnWidth = 0d; foreach (var child in group) { TileWidthModes tileWidth; var contentPresenter = child as ContentPresenter; if (contentPresenter != null && contentPresenter.Content != null && contentPresenter.Content is DependencyObject) { var dependencyContent = (DependencyObject)contentPresenter.Content; tileWidth = GetTileWidthMode(dependencyContent); child.Visibility = MetroTiles.GetTileVisibility(dependencyContent); } else { tileWidth = GetTileWidthMode(child); } if (tileWidth == TileWidthModes.Default) { tileWidth = DefaultTileWidth; } if (child.Visibility != Visibility.Visible) { continue; } switch (tileWidth) { case TileWidthModes.Tiny: if (currentTinyCount == 0 && top > absoluteTop && top + tileHeight > availableSize.Height) // We are beyond the bottom and can do something about it { top = absoluteTop; left += tileWidthDouble + horizontalSpacing; groupWidth += currentMaxColumnWidth + horizontalSpacing; currentMaxColumnWidth = 0d; } var tinyAreaLeft = left; if (currentNormalCount == 1) { tinyAreaLeft += tileWidthNormal + horizontalSpacing; } switch (currentTinyCount) { case 0: var tinyTileRect0 = GeometryHelper.NewRect(tinyAreaLeft, top, tileWidthTiny, tileWidthTiny); methodToCall(child, tinyTileRect0); heightUsed = Math.Max(heightUsed, tinyTileRect0.Bottom); widthUsed = Math.Max(widthUsed, tinyTileRect0.Right); currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthTiny); break; case 1: var tinyTileRect1 = GeometryHelper.NewRect(tinyAreaLeft + horizontalSpacing + tileWidthTiny, top, tileWidthTiny, tileWidthTiny); methodToCall(child, tinyTileRect1); heightUsed = Math.Max(heightUsed, tinyTileRect1.Bottom); widthUsed = Math.Max(widthUsed, tinyTileRect1.Right); currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny + horizontalSpacing + tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthNormal); break; case 2: var tinyTileRect2 = GeometryHelper.NewRect(tinyAreaLeft, top + verticalSpacing + tileWidthTiny, tileWidthTiny, tileWidthTiny); methodToCall(child, tinyTileRect2); heightUsed = Math.Max(heightUsed, tinyTileRect2.Bottom); widthUsed = Math.Max(widthUsed, tinyTileRect2.Right); currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny + horizontalSpacing + tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthNormal); break; case 3: var tinyTileRect3 = GeometryHelper.NewRect(tinyAreaLeft + horizontalSpacing + tileWidthTiny, top + verticalSpacing + tileWidthTiny, tileWidthTiny, tileWidthTiny); methodToCall(child, tinyTileRect3); heightUsed = Math.Max(heightUsed, tinyTileRect3.Bottom); widthUsed = Math.Max(widthUsed, tinyTileRect3.Right); currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny + horizontalSpacing + tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthNormal); break; } currentTinyCount++; if (currentTinyCount > 3) { currentNormalCount++; currentTinyCount = 0; } if (currentNormalCount > 1) { top += tileHeight + verticalSpacing; currentNormalCount = 0; } break; case TileWidthModes.Normal: if (currentNormalCount == 1 && currentTinyCount > 0) { top += tileHeight + verticalSpacing; currentNormalCount = 0; } if (currentNormalCount == 0 && top > absoluteTop && top + tileHeight > availableSize.Height) // We are beyond the bottom and can do something about it { top = absoluteTop; left += tileWidthDouble + horizontalSpacing; groupWidth += currentMaxColumnWidth + horizontalSpacing; currentMaxColumnWidth = 0d; } var normalTileRect = GeometryHelper.NewRect(currentNormalCount == 1 ? left + tileWidthNormal + horizontalSpacing : left, top, tileWidthNormal, tileHeight); currentTinyCount = 0; currentNormalCount++; methodToCall(child, normalTileRect); heightUsed = Math.Max(heightUsed, normalTileRect.Bottom); widthUsed = Math.Max(widthUsed, normalTileRect.Right); currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 1 ? tileWidthNormal : tileWidthDouble); if (currentNormalCount > 1) { top += tileHeight + verticalSpacing; currentNormalCount = 0; } break; case TileWidthModes.Double: if (currentNormalCount > 0) { top += tileHeight + verticalSpacing; } if (currentTinyCount > 0) { top += tileHeight + verticalSpacing; } if (top > absoluteTop && top + tileHeight > availableSize.Height) // We are beyond the bottom and can do something about it { top = absoluteTop; left += tileWidthDouble + horizontalSpacing; groupWidth += currentMaxColumnWidth + horizontalSpacing; } currentNormalCount = 0; currentTinyCount = 0; var dobleTileRect = GeometryHelper.NewRect(left, top, tileWidthDouble, tileHeight); methodToCall(child, dobleTileRect); heightUsed = Math.Max(heightUsed, dobleTileRect.Bottom); widthUsed = Math.Max(widthUsed, dobleTileRect.Right); currentMaxColumnWidth = tileWidthDouble; top += tileHeight + verticalSpacing; break; case TileWidthModes.DoubleSquare: if (currentNormalCount > 0) { top += tileHeight + verticalSpacing; } if (currentTinyCount > 0) { top += tileHeight + verticalSpacing; } if (top > absoluteTop && top + tileWidthDouble > availableSize.Height) // We are beyond the bottom and can do something about it { top = absoluteTop; left += tileWidthDouble + horizontalSpacing; groupWidth += currentMaxColumnWidth + horizontalSpacing; } currentNormalCount = 0; currentTinyCount = 0; var dobleSquareTileRect = GeometryHelper.NewRect(left, top, tileWidthDouble, tileWidthDouble); methodToCall(child, dobleSquareTileRect); heightUsed = Math.Max(heightUsed, dobleSquareTileRect.Bottom); widthUsed = Math.Max(widthUsed, dobleSquareTileRect.Right); currentMaxColumnWidth = tileWidthDouble; top += tileWidthDouble + verticalSpacing; break; } // Possible headers if (RenderHeaders && _headers.Count > groupCount) { _headers[groupCount].RenderRect = GeometryHelper.NewRect(groupLeft, 0d, groupWidth, _headers[groupCount].FormattedText.Height + 4); InvalidateVisual(); } } top = absoluteTop; left += horizontalGroupSpacing - horizontalSpacing; left += currentMaxColumnWidth; } //return GeometryHelper.NewSize(left + tileWidthDouble, top + tileHeight); return(GeometryHelper.NewSize(widthUsed, heightUsed)); } catch (Exception ex) { Console.Write(ex.Message); throw; } }