public ListDependencyProperties()
        {
            InitializeComponent();

            DataContext = this;

            CopyProps = new ViewAction(execute: (a, o) => Clipboard.SetText(DependencyPropList));

            var layout = new MetroTiles();

            Title = layout.ToString();
            DependencyProps = GetDependencyProperties(layout);
        }
Пример #2
0
        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;
            }
        }