Exemplo n.º 1
0
        private static void AddInlineTextRun(TextBlock uiRichTB, AdaptiveTextRun textRun, AdaptiveRenderContext context)
        {
            Span textRunSpan;

            if (textRun.SelectAction != null && context.Config.SupportsInteractivity)
            {
                Hyperlink selectActionLink = new Hyperlink();
                selectActionLink.Click += (sender, e) =>
                {
                    context.InvokeAction(uiRichTB, new AdaptiveActionEventArgs(textRun.SelectAction));
                    e.Handled = true;
                };

                textRunSpan = selectActionLink as Span;
            }
            else
            {
                textRunSpan = new Span();
            }

            // Handle Date/Time parsing
            string text = RendererUtilities.ApplyTextFunctions(textRun.Text, context.Lang);

            textRunSpan.Inlines.Add(text);

            textRunSpan.Style = context.GetStyle($"Adaptive.{textRun.Type}");

            textRunSpan.FontFamily = new FontFamily(RendererUtil.GetFontFamilyFromList(context.Config.GetFontFamily(textRun.FontType)));

            textRunSpan.FontWeight = FontWeight.FromOpenTypeWeight(context.Config.GetFontWeight(textRun.FontType, textRun.Weight));

            textRunSpan.FontSize = context.Config.GetFontSize(textRun.FontType, textRun.Size);

            if (textRun.Italic)
            {
                textRunSpan.FontStyle = FontStyles.Italic;
            }

            if (textRun.Strikethrough)
            {
                textRunSpan.TextDecorations.Add(TextDecorations.Strikethrough);
            }

            if (textRun.Underline)
            {
                textRunSpan.TextDecorations.Add(TextDecorations.Underline);
            }

            if (textRun.Highlight)
            {
                textRunSpan.SetHighlightColor(textRun.Color, textRun.IsSubtle, context);
            }

            textRunSpan.SetColor(textRun.Color, textRun.IsSubtle, context);

            uiRichTB.Inlines.Add(textRunSpan);
        }
        public static FrameworkElement Render(AdaptiveColumn column, AdaptiveRenderContext context)
        {
            var uiContainer = new Grid();

            uiContainer.Style = context.GetStyle("Adaptive.Column");
            uiContainer.SetBackgroundSource(column.BackgroundImage, context);

            // Keep track of ContainerStyle.ForegroundColors before Container is rendered
            var parentRenderArgs = context.RenderArgs;
            // This is the renderArgs that will be passed down to the children
            var childRenderArgs = new AdaptiveRenderArgs(parentRenderArgs);

            Border border = new Border();

            border.Child = uiContainer;

            bool inheritsStyleFromParent = !column.Style.HasValue;
            bool columnHasPadding        = false;

            if (!inheritsStyleFromParent)
            {
                columnHasPadding = AdaptiveContainerRenderer.ApplyPadding(border, uiContainer, column, parentRenderArgs, context);

                // Apply background color
                ContainerStyleConfig containerStyle = context.Config.ContainerStyles.GetContainerStyleConfig(column.Style);
                border.Background = context.GetColorBrush(containerStyle.BackgroundColor);

                childRenderArgs.ForegroundColors = containerStyle.ForegroundColors;
            }

            childRenderArgs.ParentStyle = (inheritsStyleFromParent) ? parentRenderArgs.ParentStyle : column.Style.Value;

            // If the column has no padding or has padding and doesn't bleed, then the children can bleed
            // to the side the column would have bled
            if (columnHasPadding)
            {
                childRenderArgs.BleedDirection = BleedDirection.Both;
            }

            // If either this column or an ancestor had padding, then the children will have an ancestor with padding
            childRenderArgs.HasParentWithPadding = (columnHasPadding || parentRenderArgs.HasParentWithPadding);
            context.RenderArgs = childRenderArgs;

            AdaptiveContainerRenderer.AddContainerElements(uiContainer, column.Items, context);

            RendererUtil.ApplyVerticalContentAlignment(uiContainer, column);
            RendererUtil.ApplyIsVisible(uiContainer, column);
            uiContainer.MinHeight = column.PixelMinHeight;

            // Revert context's value to that of outside the Column
            context.RenderArgs = parentRenderArgs;

            return(RendererUtil.ApplySelectAction(border, column, context));
        }
Exemplo n.º 3
0
        private static TextBlock CreateControl(AdaptiveTextBlock textBlock, AdaptiveRenderContext context)
        {
            Marked marked = new Marked();

            marked.Options.Renderer = new AdaptiveXamlMarkdownRenderer();
            marked.Options.Mangle   = false;
            marked.Options.Sanitize = true;

            string text = RendererUtilities.ApplyTextFunctions(textBlock.Text, context.Lang);
            // uiTextBlock.Text = textBlock.Text;
            string       xaml         = $"<TextBlock  xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">{marked.Parse(text)}</TextBlock>";
            StringReader stringReader = new StringReader(xaml);

            XmlReader xmlReader   = XmlReader.Create(stringReader);
            var       uiTextBlock = (System.Windows.Controls.TextBlock)XamlReader.Load(xmlReader);

            uiTextBlock.Style = context.GetStyle($"Adaptive.{textBlock.Type}");

            uiTextBlock.TextWrapping = TextWrapping.NoWrap;

            uiTextBlock.FontFamily = new FontFamily(RendererUtil.GetFontFamilyFromList(context.Config.GetFontFamily(textBlock.FontStyle)));
            uiTextBlock.FontWeight = FontWeight.FromOpenTypeWeight(context.Config.GetFontWeight(textBlock.FontStyle, textBlock.Weight));
            uiTextBlock.FontSize   = context.Config.GetFontSize(textBlock.FontStyle, textBlock.Size);

            uiTextBlock.TextTrimming = TextTrimming.CharacterEllipsis;

            if (textBlock.Italic)
            {
                uiTextBlock.FontStyle = FontStyles.Italic;
            }

            if (textBlock.Strikethrough)
            {
                uiTextBlock.TextDecorations = TextDecorations.Strikethrough;
            }

            if (textBlock.HorizontalAlignment != AdaptiveHorizontalAlignment.Left)
            {
                System.Windows.TextAlignment alignment;
                if (Enum.TryParse <System.Windows.TextAlignment>(textBlock.HorizontalAlignment.ToString(), out alignment))
                {
                    uiTextBlock.TextAlignment = alignment;
                }
            }

            if (textBlock.Wrap)
            {
                uiTextBlock.TextWrapping = TextWrapping.Wrap;
            }

            return(uiTextBlock);
        }
        public static FrameworkElement Render(AdaptiveColumn column, AdaptiveRenderContext context)
        {
            var uiContainer = new Grid();

            uiContainer.Style = context.GetStyle("Adaptive.Column");
            uiContainer.SetBackgroundSource(column.BackgroundImage, context);

            // Keep track of ContainerStyle.ForegroundColors before Container is rendered
            var parentRenderArgs  = context.RenderArgs;
            var elementRenderArgs = new AdaptiveRenderArgs(parentRenderArgs);

            Border border = new Border();

            border.Child = uiContainer;

            bool inheritsStyleFromParent = !column.Style.HasValue;
            bool columnHasPadding        = false;

            if (!inheritsStyleFromParent)
            {
                columnHasPadding = AdaptiveContainerRenderer.ApplyPadding(border, uiContainer, column, parentRenderArgs, context);

                // Apply background color
                ContainerStyleConfig containerStyle = context.Config.ContainerStyles.GetContainerStyleConfig(column.Style);
                border.Background = context.GetColorBrush(containerStyle.BackgroundColor);

                elementRenderArgs.ForegroundColors = containerStyle.ForegroundColors;
            }

            elementRenderArgs.ParentStyle = (inheritsStyleFromParent) ? parentRenderArgs.ParentStyle : column.Style.Value;
            if ((parentRenderArgs.ColumnRelativePosition == ColumnPositionEnum.Begin) ||
                (parentRenderArgs.ColumnRelativePosition == ColumnPositionEnum.End))
            {
                elementRenderArgs.ColumnRelativePosition = ColumnPositionEnum.Intermediate;
            }

            elementRenderArgs.HasParentWithPadding = columnHasPadding;
            context.RenderArgs = elementRenderArgs;

            AdaptiveContainerRenderer.AddContainerElements(uiContainer, column.Items, context);

            RendererUtil.ApplyVerticalContentAlignment(uiContainer, column);
            RendererUtil.ApplyIsVisible(uiContainer, column);
            uiContainer.MinHeight = column.PixelMinHeight;

            // Revert context's value to that of outside the Column
            context.RenderArgs = parentRenderArgs;

            return(RendererUtil.ApplySelectAction(border, column, context));
        }
        public static FrameworkElement Render(AdaptiveContainer container, AdaptiveRenderContext context)
        {
            var uiContainer = new Grid();

            uiContainer.Style = context.GetStyle("Adaptive.Container");
            uiContainer.SetBackgroundSource(container.BackgroundImage, context);

            // Keep track of ContainerStyle.ForegroundColors before Container is rendered
            var parentRenderArgs  = context.RenderArgs;
            var elementRenderArgs = new AdaptiveRenderArgs(parentRenderArgs);

            Grid uiOuterContainer = new Grid();

            uiOuterContainer.Children.Add(uiContainer);
            Border border = new Border();

            border.Child = uiOuterContainer;

            RendererUtil.ApplyVerticalContentAlignment(uiContainer, container);
            RendererUtil.ApplyIsVisible(border, container);
            uiContainer.MinHeight = container.PixelMinHeight;

            bool inheritsStyleFromParent = !container.Style.HasValue;
            bool hasPadding = false;

            if (!inheritsStyleFromParent)
            {
                hasPadding = ApplyPadding(border, uiOuterContainer, container, parentRenderArgs, context);

                // Apply background color
                ContainerStyleConfig containerStyle = context.Config.ContainerStyles.GetContainerStyleConfig(container.Style);
                border.Background = context.GetColorBrush(containerStyle.BackgroundColor);

                elementRenderArgs.ForegroundColors = containerStyle.ForegroundColors;
            }

            // Modify context outer parent style so padding necessity can be determined
            elementRenderArgs.ParentStyle          = (inheritsStyleFromParent) ? parentRenderArgs.ParentStyle : container.Style.Value;
            elementRenderArgs.HasParentWithPadding = (hasPadding || parentRenderArgs.HasParentWithPadding);
            context.RenderArgs = elementRenderArgs;

            AddContainerElements(uiContainer, container.Items, context);

            // Revert context's value to that of outside the Container
            context.RenderArgs = parentRenderArgs;

            return(RendererUtil.ApplySelectAction(border, container, context));
        }
        public static FrameworkElement Render(AdaptiveColumnSet columnSet, AdaptiveRenderContext context)
        {
            var uiColumnSet = new Grid();

            uiColumnSet.Style = context.GetStyle($"Adaptive.{columnSet.Type}");

            // Keep track of ContainerStyle.ForegroundColors before Container is rendered
            var parentRenderArgs = context.RenderArgs;
            // This is the renderArgs that will be the base for all the columns renderArgs
            var childrenRenderArgs = new AdaptiveRenderArgs(parentRenderArgs);

            Border border = new Border();

            border.Child = uiColumnSet;

            bool inheritsStyleFromParent = !columnSet.Style.HasValue;
            bool hasPadding = false;

            if (!inheritsStyleFromParent)
            {
                hasPadding = AdaptiveContainerRenderer.ApplyPadding(border, uiColumnSet, columnSet, parentRenderArgs, context);

                // Apply background color
                var columnSetStyle = context.Config.ContainerStyles.GetContainerStyleConfig(columnSet.Style);

                border.Background = context.GetColorBrush(columnSetStyle.BackgroundColor);
                childrenRenderArgs.ForegroundColors = columnSetStyle.ForegroundColors;
            }

            childrenRenderArgs.ParentStyle = (inheritsStyleFromParent) ? parentRenderArgs.ParentStyle : columnSet.Style.Value;

            for (int i = 0; i < columnSet.Columns.Count; ++i)
            {
                AdaptiveColumn column = columnSet.Columns[i];

                var childRenderArgs = new AdaptiveRenderArgs(childrenRenderArgs);
                // Reset up and down bleed for columns as that behaviour shouldn't be changed
                childRenderArgs.BleedDirection |= (BleedDirection.BleedUp | BleedDirection.BleedDown);

                if (i != 0)
                {
                    // Only the first column can bleed to the left
                    childRenderArgs.BleedDirection &= ~BleedDirection.BleedLeft;
                }

                if (i != columnSet.Columns.Count - 1)
                {
                    // Only the last column can bleed to the right
                    childRenderArgs.BleedDirection &= ~BleedDirection.BleedRight;
                }

                context.RenderArgs = childRenderArgs;

                FrameworkElement uiContainer = context.Render(column);

                // If the column couldn't be rendered and the fallback is 'drop'
                if (uiContainer != null)
                {
                    TagContent tag = null;

                    // Add vertical Separator
                    if (uiColumnSet.ColumnDefinitions.Count > 0 && (column.Separator || column.Spacing != AdaptiveSpacing.None))
                    {
                        var uiSep = new Grid();
                        uiSep.Style = context.GetStyle($"Adaptive.VerticalSeparator");

                        uiSep.VerticalAlignment = VerticalAlignment.Stretch;

                        int spacing = context.Config.GetSpacing(column.Spacing);
                        uiSep.Margin = new Thickness(spacing / 2.0, 0, spacing / 2.0, 0);

                        uiSep.Width = context.Config.Separator.LineThickness;
                        if (column.Separator && context.Config.Separator.LineColor != null)
                        {
                            uiSep.Background = context.GetColorBrush(context.Config.Separator.LineColor);
                        }

                        tag = new TagContent(uiSep, uiColumnSet);

                        uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition()
                        {
                            Width = GridLength.Auto
                        });
                        Grid.SetColumn(uiSep, uiColumnSet.ColumnDefinitions.Count - 1);
                        uiColumnSet.Children.Add(uiSep);
                    }
                    else
                    {
                        tag = new TagContent(null, uiColumnSet);
                    }

                    // do some sizing magic using the magic GridUnitType.Star
                    var width = column.Width?.ToLower();
                    if (string.IsNullOrEmpty(width))
#pragma warning disable CS0618 // Type or member is obsolete
                    {
                        width = column.Size?.ToLower();
                    }
#pragma warning restore CS0618 // Type or member is obsolete

                    ColumnDefinition columnDefinition = null;

                    if (width == null || width == AdaptiveColumnWidth.Stretch.ToLower())
                    {
                        columnDefinition = new ColumnDefinition()
                        {
                            Width = new GridLength(1, GridUnitType.Star)
                        };
                    }
                    else if (width == AdaptiveColumnWidth.Auto.ToLower())
                    {
                        columnDefinition = new ColumnDefinition()
                        {
                            Width = GridLength.Auto
                        };
                    }
                    else
                    {
                        if (double.TryParse(width, out double val) && val >= 0)
                        {
                            // Weighted proportion (number only)
                            columnDefinition = new ColumnDefinition()
                            {
                                Width = new GridLength(val, GridUnitType.Star)
                            };
                        }
                        else if (width.EndsWith("px") && double.TryParse(width.Substring(0, width.Length - 2), out double pxVal) && pxVal >= 0)
                        {
                            // Exact pixel (number followed by "px")
                            columnDefinition = new ColumnDefinition()
                            {
                                Width = new GridLength((int)pxVal, GridUnitType.Pixel)
                            };
                        }
                        else
                        {
                            columnDefinition = new ColumnDefinition()
                            {
                                Width = GridLength.Auto
                            };
                        }
                    }

                    // Store the column definition in the tag so we can toggle the visibility later
                    tag.ColumnDefinition = columnDefinition;
                    tag.ViewIndex        = uiColumnSet.ColumnDefinitions.Count;

                    uiColumnSet.ColumnDefinitions.Add(columnDefinition);

                    uiContainer.Tag = tag;

                    Grid.SetColumn(uiContainer, uiColumnSet.ColumnDefinitions.Count - 1);
                    uiColumnSet.Children.Add(uiContainer);

                    context.SetVisibility(uiContainer, column.IsVisible, tag);
                }
            }

            context.ResetSeparatorVisibilityInsideContainer(uiColumnSet);

            // Revert context's value to that of outside the Container
            context.RenderArgs = parentRenderArgs;

            uiColumnSet.MinHeight = columnSet.PixelMinHeight;

            return(RendererUtil.ApplySelectAction(border, columnSet, context));
        }
        public static FrameworkElement Render(AdaptiveContainer container, AdaptiveRenderContext context)
        {
            var uiContainer = new Grid();

            uiContainer.Style = context.GetStyle("Adaptive.Container");
            uiContainer.SetBackgroundSource(container.BackgroundImage, context);

            // Keep track of ContainerStyle.ForegroundColors before Container is rendered
            var parentRenderArgs = context.RenderArgs;
            // This is the renderArgs that will be passed down to the children
            var childRenderArgs = new AdaptiveRenderArgs(parentRenderArgs);

            Grid uiOuterContainer = new Grid();

            uiOuterContainer.Children.Add(uiContainer);
            Border border = new Border();

            border.Child = uiOuterContainer;

            RendererUtil.ApplyVerticalContentAlignment(uiContainer, container);
            uiContainer.MinHeight = container.PixelMinHeight;

            bool inheritsStyleFromParent = !container.Style.HasValue;
            bool hasPadding = false;

            if (!inheritsStyleFromParent)
            {
                hasPadding = ApplyPadding(border, uiOuterContainer, container, parentRenderArgs, context);

                // Apply background color
                ContainerStyleConfig containerStyle = context.Config.ContainerStyles.GetContainerStyleConfig(container.Style);
                border.Background = context.GetColorBrush(containerStyle.BackgroundColor);

                childRenderArgs.ForegroundColors = containerStyle.ForegroundColors;
            }

            switch (container.VerticalContentAlignment)
            {
            case AdaptiveVerticalContentAlignment.Center:
                uiContainer.VerticalAlignment = VerticalAlignment.Center;
                break;

            case AdaptiveVerticalContentAlignment.Bottom:
                uiContainer.VerticalAlignment = VerticalAlignment.Bottom;
                break;

            case AdaptiveVerticalContentAlignment.Top:
            default:
                break;
            }

            if (hasPadding)
            {
                childRenderArgs.BleedDirection = BleedDirection.BleedAll;
            }

            // Modify context outer parent style so padding necessity can be determined
            childRenderArgs.ParentStyle          = (inheritsStyleFromParent) ? parentRenderArgs.ParentStyle : container.Style.Value;
            childRenderArgs.HasParentWithPadding = (hasPadding || parentRenderArgs.HasParentWithPadding);
            context.RenderArgs = childRenderArgs;

            AddContainerElements(uiContainer, container.Items, context);

            // Revert context's value to that of outside the Container
            context.RenderArgs = parentRenderArgs;

            return(RendererUtil.ApplySelectAction(border, container, context));
        }
        public static void AddContainerElements(Grid uiContainer, IList <AdaptiveElement> elements, AdaptiveRenderContext context)
        {
            foreach (var cardElement in elements)
            {
                // each element has a row
                FrameworkElement uiElement = context.Render(cardElement);
                if (uiElement != null)
                {
                    if (cardElement.Separator && uiContainer.Children.Count > 0)
                    {
                        AddSeparator(context, cardElement, uiContainer);
                    }
                    else if (uiContainer.Children.Count > 0)
                    {
                        var       spacing        = context.Config.GetSpacing(cardElement.Spacing);
                        Thickness renderedMargin = uiElement.Margin;
                        uiElement.Margin = new Thickness(renderedMargin.Left,
                                                         renderedMargin.Top + spacing,
                                                         renderedMargin.Right,
                                                         renderedMargin.Bottom);
                    }

                    if (cardElement.Type == "Container" || cardElement.Type == "ColumnSet")
                    {
                        AdaptiveCollectionElement collectionElement = (AdaptiveCollectionElement)cardElement;
                        uiElement.MinHeight = collectionElement.PixelMinHeight;
                    }

                    if (cardElement.Height != AdaptiveHeight.Stretch)
                    {
                        uiContainer.RowDefinitions.Add(new RowDefinition()
                        {
                            Height = GridLength.Auto
                        });
                        Grid.SetRow(uiElement, uiContainer.RowDefinitions.Count - 1);

                        RendererUtil.ApplyIsVisible(uiElement, cardElement);
                        Grid.SetRow(uiElement, uiContainer.RowDefinitions.Count - 1);
                        uiContainer.Children.Add(uiElement);
                    }
                    else
                    {
                        if (cardElement.Type == "Container")
                        {
                            RendererUtil.ApplyIsVisible(uiElement, cardElement);
                            uiContainer.RowDefinitions.Add(new RowDefinition()
                            {
                                Height = new GridLength(1, GridUnitType.Star)
                            });
                            Grid.SetRow(uiElement, uiContainer.RowDefinitions.Count - 1);
                            uiContainer.Children.Add(uiElement);
                        }
                        else
                        {
                            StackPanel panel = new StackPanel();
                            RendererUtil.ApplyIsVisible(panel, cardElement);
                            if (!String.IsNullOrEmpty(cardElement.Id))
                            {
                                panel.Name = cardElement.Id;
                            }
                            panel.Children.Add(uiElement);

                            uiContainer.RowDefinitions.Add(new RowDefinition()
                            {
                                Height = new GridLength(1, GridUnitType.Star)
                            });
                            Grid.SetRow(panel, uiContainer.RowDefinitions.Count - 1);
                            uiContainer.Children.Add(panel);
                        }
                    }
                }
            }
        }
        public static FrameworkElement Render(AdaptiveFactSet factSet, AdaptiveRenderContext context)
        {
            var uiFactSet = new Grid();

            // grid.Margin = factSet.Theme.FactSetMargins;
            uiFactSet.Style = context.GetStyle("Adaptive.FactSet");

            uiFactSet.ColumnDefinitions.Add(new ColumnDefinition()
            {
                Width = GridLength.Auto
            });
            uiFactSet.ColumnDefinitions.Add(new ColumnDefinition()
            {
                Width = new GridLength(1, GridUnitType.Star)
            });
            int iRow = 0;

            foreach (var fact in factSet.Facts)
            {
                var uiTitle = context.Render(new AdaptiveTextBlock()
                {
                    Size     = context.Config.FactSet.Title.Size,
                    Color    = context.Config.FactSet.Title.Color,
                    IsSubtle = context.Config.FactSet.Title.IsSubtle,
                    Weight   = context.Config.FactSet.Title.Weight,
                    Wrap     = context.Config.FactSet.Title.Wrap,
                    MaxWidth = context.Config.FactSet.Title.MaxWidth,
                    Text     = fact.Title
                });

                uiTitle.Style  = context.GetStyle("Adaptive.Fact.Title");
                uiTitle.Margin = new Thickness(left: 0, top: 0, right: context.Config.FactSet.Spacing, bottom: 0);

                var uiValue = context.Render(new AdaptiveTextBlock()
                {
                    Size     = context.Config.FactSet.Value.Size,
                    Color    = context.Config.FactSet.Value.Color,
                    IsSubtle = context.Config.FactSet.Value.IsSubtle,
                    Weight   = context.Config.FactSet.Value.Weight,
                    Wrap     = context.Config.FactSet.Value.Wrap,
                    // MaxWidth is not applicable to the Value field of the Fact
                    // so ignore it.
                    Text = fact.Value
                });

                uiValue.Style = context.GetStyle("Adaptive.Fact.Value");

                uiFactSet.RowDefinitions.Add(new RowDefinition()
                {
                    Height = GridLength.Auto
                });

                Grid.SetColumn(uiTitle, 0);
                Grid.SetRow(uiTitle, iRow);
                uiFactSet.Children.Add(uiTitle);

                Grid.SetColumn(uiValue, 1);
                Grid.SetRow(uiValue, iRow++);
                uiFactSet.Children.Add(uiValue);
            }

            RendererUtil.ApplyIsVisible(uiFactSet, factSet);

            return(uiFactSet);
        }
        public static FrameworkElement Render(AdaptiveImage image, AdaptiveRenderContext context)
        {
            FrameworkElement uiBorder = null;
            var uiImage = new Image();

            // Try to resolve the image URI
            Uri finalUri = context.Config.ResolveFinalAbsoluteUri(image.Url);

            if (finalUri == null)
            {
                return(uiImage);
            }

            uiImage.SetSource(image, finalUri, context);

            uiImage.SetHorizontalAlignment(image.HorizontalAlignment);

            string style = $"Adaptive.{image.Type}";

            if (image.Style == AdaptiveImageStyle.Person)
            {
                style += $".{image.Style}";

                var mask = new RadialGradientBrush()
                {
                    GradientOrigin = new Point(0.5, 0.5),
                    Center         = new Point(0.5, 0.5),
                    RadiusX        = 0.5,
                    RadiusY        = 0.5,
                    GradientStops  = new GradientStopCollection()
                };
                mask.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#ffffffff"), 1.0));
                mask.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#00ffffff"), 1.0));
                uiImage.OpacityMask = mask;
            }
            uiImage.Style = context.GetStyle(style);

            if (image.PixelHeight == 0 && image.PixelWidth == 0)
            {
                uiImage.SetImageProperties(image, context);
            }

            // If we have a background color, we'll create a border for the background and put the image on top
            if (!string.IsNullOrEmpty(image.BackgroundColor))
            {
                Color color = (Color)ColorConverter.ConvertFromString(image.BackgroundColor);
                if (color.A != 0)
                {
                    uiBorder = new Border()
                    {
                        Background          = new SolidColorBrush(color),
                        Child               = uiImage,
                        Width               = uiImage.Width,
                        Height              = uiImage.Height,
                        HorizontalAlignment = uiImage.HorizontalAlignment,
                        VerticalAlignment   = uiImage.VerticalAlignment,
                        OpacityMask         = uiImage.OpacityMask
                    };
                }
            }

            return(RendererUtil.ApplySelectAction(uiBorder ?? uiImage, image, context));
        }
        public static FrameworkElement Render(AdaptiveColumnSet columnSet, AdaptiveRenderContext context)
        {
            var uiColumnSet = new Grid();

            uiColumnSet.Style = context.GetStyle($"Adaptive.{columnSet.Type}");

            // Keep track of ContainerStyle.ForegroundColors before Container is rendered
            var parentRenderArgs  = context.RenderArgs;
            var elementRenderArgs = new AdaptiveRenderArgs(parentRenderArgs);

            Border border = new Border();

            border.Child = uiColumnSet;

            bool inheritsStyleFromParent = !columnSet.Style.HasValue;
            bool hasPadding = false;

            if (!inheritsStyleFromParent)
            {
                hasPadding = AdaptiveContainerRenderer.ApplyPadding(border, uiColumnSet, columnSet, parentRenderArgs, context);

                // Apply background color
                var columnSetStyle = context.Config.ContainerStyles.GetContainerStyleConfig(columnSet.Style);

                border.Background = context.GetColorBrush(columnSetStyle.BackgroundColor);
                elementRenderArgs.ForegroundColors = columnSetStyle.ForegroundColors;
            }

            elementRenderArgs.ParentStyle          = (inheritsStyleFromParent) ? parentRenderArgs.ParentStyle : columnSet.Style.Value;
            elementRenderArgs.HasParentWithPadding = (hasPadding || parentRenderArgs.HasParentWithPadding);

            for (int i = 0; i < columnSet.Columns.Count; ++i)
            {
                AdaptiveColumn column = columnSet.Columns[i];

                var columnRenderArgs = new AdaptiveRenderArgs(elementRenderArgs);
                if (columnSet.Columns.Count == 1)
                {
                    columnRenderArgs.ColumnRelativePosition = ColumnPositionEnum.Only;
                }
                else
                {
                    if (i == 0)
                    {
                        columnRenderArgs.ColumnRelativePosition = ColumnPositionEnum.Begin;
                    }
                    else if (i == (columnSet.Columns.Count - 1))
                    {
                        columnRenderArgs.ColumnRelativePosition = ColumnPositionEnum.End;
                    }
                    else
                    {
                        columnRenderArgs.ColumnRelativePosition = ColumnPositionEnum.Intermediate;
                    }
                }
                context.RenderArgs = columnRenderArgs;

                FrameworkElement uiContainer = context.Render(column);

                // Add vertical Seperator
                if (uiColumnSet.ColumnDefinitions.Count > 0)
                {
                    if (column.Separator || column.Spacing != AdaptiveSpacing.None)
                    {
                        var uiSep = new Grid();
                        uiSep.Style = context.GetStyle($"Adaptive.VerticalSeparator");

                        uiSep.VerticalAlignment = VerticalAlignment.Stretch;

                        int spacing = context.Config.GetSpacing(column.Spacing);
                        uiSep.Margin = new Thickness(spacing / 2.0, 0, spacing / 2.0, 0);

                        uiSep.Width = context.Config.Separator.LineThickness;
                        if (column.Separator && context.Config.Separator.LineColor != null)
                        {
                            uiSep.Background = context.GetColorBrush(context.Config.Separator.LineColor);
                        }

                        uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition()
                        {
                            Width = GridLength.Auto
                        });
                        Grid.SetColumn(uiSep, uiColumnSet.ColumnDefinitions.Count - 1);
                        uiColumnSet.Children.Add(uiSep);
                    }
                }

                // do some sizing magic using the magic GridUnitType.Star
                var width = column.Width?.ToLower();
                if (string.IsNullOrEmpty(width))
#pragma warning disable CS0618 // Type or member is obsolete
                {
                    width = column.Size?.ToLower();
                }
#pragma warning restore CS0618 // Type or member is obsolete
                if (width == null || width == AdaptiveColumnWidth.Stretch.ToLower())
                {
                    uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition()
                    {
                        Width = new GridLength(1, GridUnitType.Star)
                    });
                }
                else if (width == AdaptiveColumnWidth.Auto.ToLower())
                {
                    uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition()
                    {
                        Width = GridLength.Auto
                    });
                }
                else
                {
                    if (double.TryParse(width, out double val) && val >= 0)
                    {
                        // Weighted proportion (number only)
                        uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition()
                        {
                            Width = new GridLength(val, GridUnitType.Star)
                        });
                    }
                    else if (width.EndsWith("px") && double.TryParse(width.Substring(0, width.Length - 2), out double pxVal) && pxVal >= 0)
                    {
                        // Exact pixel (number followed by "px")
                        uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition()
                        {
                            Width = new GridLength((int)pxVal, GridUnitType.Pixel)
                        });
                    }
                    else
                    {
                        uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition()
                        {
                            Width = GridLength.Auto
                        });
                    }
                }

                Grid.SetColumn(uiContainer, uiColumnSet.ColumnDefinitions.Count - 1);
                uiColumnSet.Children.Add(uiContainer);
            }

            // Revert context's value to that of outside the Container
            context.RenderArgs = parentRenderArgs;

            RendererUtil.ApplyIsVisible(uiColumnSet, columnSet);
            uiColumnSet.MinHeight = columnSet.PixelMinHeight;

            return(RendererUtil.ApplySelectAction(border, columnSet, context));
        }