Esempio n. 1
0
        /// <summary>
        /// When overridden in a derived class, positions child elements and determines a size for a <see cref="T:System.Windows.FrameworkElement"/> derived class.
        /// </summary>
        /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
        /// <returns>
        /// The actual size used.
        /// </returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            if (Children.Count != 2)
            {
                return(base.ArrangeOverride(finalSize));                     // Not much we can do until we have exactly two elements;
            }
            // First, we check whether we have any headers
            _headers.Clear();
            var header1 = GetCaption(Children[0]);
            var header2 = GetCaption(Children[1]);

            if (Orientation == Orientation.Vertical)
            {
                var maxHeaderHeight = 0d;
                if (!string.IsNullOrEmpty(header1) || !string.IsNullOrEmpty(header2))
                {
                    _headers.Add(new AutoHeaderTextRenderInfo {
                        Text = header1, FormattedText = new FormattedText(header1, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush)
                    });
                    _headers.Add(new AutoHeaderTextRenderInfo {
                        Text = header2, FormattedText = new FormattedText(header2, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush)
                    });
                    maxHeaderHeight = Math.Max(_headers[0].FormattedText.Height, _headers[1].FormattedText.Height);
                }

                var top    = maxHeaderHeight + CaptionSpacing;
                var height = Math.Max(finalSize.Height - top, 0);
                var width  = Math.Max((finalSize.Width - Spacing) / 2, 0);

                Children[0].Arrange(GeometryHelper.NewRect(0d, top, width, height));
                Children[1].Arrange(GeometryHelper.NewRect(width + Spacing, top, width, height));

                if (maxHeaderHeight > 0d)
                {
                    _headers[0].RenderRect = GeometryHelper.NewRect(0d, 0d, width, maxHeaderHeight);
                    _headers[1].RenderRect = GeometryHelper.NewRect(width + Spacing, 0d, width, maxHeaderHeight);
                }
            }
            else
            {
                var top     = 0d;
                var height  = Math.Max((finalSize.Height - Spacing) / 2, 0);
                var height1 = height;
                var height2 = height;

                if (!string.IsNullOrEmpty(header1))
                {
                    var text1 = new AutoHeaderTextRenderInfo {
                        Text = header1, FormattedText = new FormattedText(header1, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush)
                    };
                    _headers.Add(text1);
                    text1.RenderRect = GeometryHelper.NewRect(0d, 0d, finalSize.Width, text1.FormattedText.Height);
                    top     += text1.FormattedText.Height + CaptionSpacing;
                    height1 -= (text1.FormattedText.Height + CaptionSpacing);
                }

                Children[0].Arrange(GeometryHelper.NewRect(0d, top, finalSize.Width, height1));

                if (!string.IsNullOrEmpty(header2))
                {
                    var text2 = new AutoHeaderTextRenderInfo {
                        Text = header2, FormattedText = new FormattedText(header2, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush)
                    };
                    _headers.Add(text2);
                    text2.RenderRect = GeometryHelper.NewRect(0d, 0d, finalSize.Width, text2.FormattedText.Height);
                    top     += text2.FormattedText.Height + CaptionSpacing;
                    height2 -= (text2.FormattedText.Height + CaptionSpacing);
                }

                Children[1].Arrange(GeometryHelper.NewRect(0d, top, finalSize.Width, height2));
            }

            return(finalSize);
        }
Esempio n. 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;
            }
        }