public void SetVisibility(FrameworkElement element, bool isVisible, TagContent tagContent) { bool elementIsCurrentlyVisible = (element.Visibility == Visibility.Visible); element.Visibility = isVisible ? Visibility.Visible : Visibility.Collapsed; // Columns with ColumnDefinition having stars won't hide so we have to set the width to auto if (tagContent.NotAutoWidthColumnDefinition != null) { ColumnDefinition columnDefinition = new ColumnDefinition() { Width = GridLength.Auto }; if (isVisible) { columnDefinition = tagContent.NotAutoWidthColumnDefinition; } // Trying to set the same columnDefinition twice to the same element is not valid, so we have to make a check first if (!(elementIsCurrentlyVisible && isVisible)) { tagContent.ElementContainer.ColumnDefinitions[tagContent.ViewIndex] = columnDefinition; } } }
/// <summary> /// Changes the visibility of the specified elements as defined /// </summary> /// <param name="targetElements">Taget elements to change visibility</param> public void ToggleVisibility(IEnumerable <AdaptiveTargetElement> targetElements) { HashSet <Grid> elementContainers = new HashSet <Grid>(); foreach (AdaptiveTargetElement targetElement in targetElements) { var element = LogicalTreeHelper.FindLogicalNode(CardRoot, targetElement.ElementId); if (element != null && element is FrameworkElement elementFrameworkElement) { bool isCurrentlyVisible = (elementFrameworkElement.Visibility == Visibility.Visible); // if we read something with the format {"elementId": <id>", "isVisible": true} or // we just read the id and the element is not visible; // otherwise if we read something with the format {"elementId": <id>", "isVisible": false} or // we just read the id and the element is visible bool newVisibility = (targetElement.IsVisible.HasValue && targetElement.IsVisible.Value) || (!targetElement.IsVisible.HasValue && !isCurrentlyVisible); TagContent tagContent = GetTagContent(elementFrameworkElement); SetVisibility(elementFrameworkElement, newVisibility, tagContent); if (tagContent != null) { elementContainers.Add(tagContent.ParentContainerElement); } } } foreach (Grid elementContainer in elementContainers) { ResetSeparatorVisibilityInsideContainer(elementContainer); } }
/// <summary> /// Changes the visibility for the rendered element /// </summary> /// <param name="element">Rendered element to apply visibility</param> /// <param name="desiredVisibility">Visibility to be applied to the element</param> /// <param name="tagContent">Rendered element tag</param> public void SetVisibility(FrameworkElement element, bool desiredVisibility, TagContent tagContent) { bool elementIsCurrentlyVisible = (element.Visibility == Visibility.Visible); element.Visibility = desiredVisibility ? Visibility.Visible : Visibility.Collapsed; // Hides the separator if any was rendered Grid separator = tagContent.Separator; if (separator != null) { separator.Visibility = desiredVisibility ? Visibility.Visible : Visibility.Collapsed; } // Elements (Rows) with RowDefinition having stars won't hide so we have to set the width to auto // Also, trying to set the same rowDefinition twice to the same element is not valid, // so we have to make a check first if ((tagContent.RowDefinition != null) && !(elementIsCurrentlyVisible && desiredVisibility)) { RowDefinition rowDefinition = null; if (desiredVisibility) { rowDefinition = tagContent.RowDefinition; } else { // When the visibility is set to false, then set the row definition to auto rowDefinition = new RowDefinition() { Height = GridLength.Auto }; } tagContent.ParentContainerElement.RowDefinitions[tagContent.ViewIndex] = rowDefinition; } // Columns with ColumnDefinition having stars won't hide so we have to set the width to auto // Also, trying to set the same columnDefinition twice to the same element is not valid, // so we have to make a check first if ((tagContent.ColumnDefinition != null) && !(elementIsCurrentlyVisible && desiredVisibility)) { ColumnDefinition columnDefinition = null; if (desiredVisibility) { columnDefinition = tagContent.ColumnDefinition; } else { columnDefinition = new ColumnDefinition() { Width = GridLength.Auto }; } tagContent.ParentContainerElement.ColumnDefinitions[tagContent.ViewIndex] = columnDefinition; } }
/// <summary> /// Hides the first separator and fixes the visibility for the other visible separators /// </summary> /// <param name="uiContainer">Renderered element container</param> public void ResetSeparatorVisibilityInsideContainer(Grid uiContainer) { bool isFirstVisible = true; foreach (FrameworkElement element in uiContainer.Children) { if (element.Visibility == Visibility.Visible) { TagContent tagContent = GetTagContent(element); if (tagContent != null) { HandleSeparatorAndSpacing(isFirstVisible, element, tagContent); isFirstVisible = false; } } } }
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)); }
private void HandleSeparatorAndSpacing(bool isFirstVisible, FrameworkElement element, TagContent tagContent) { // Hide the spacing / separator for the first element // Separators and spacings are added as a grid Grid separator = tagContent.Separator; if (separator != null) { separator.Visibility = isFirstVisible ? Visibility.Collapsed : Visibility.Visible; } }
public static void AddContainerElements(Grid uiContainer, IList <AdaptiveElement> elements, AdaptiveRenderContext context) { // Keeping track of the index so we don't have to call IndexOf function on every iteration int index = 0; foreach (var cardElement in elements) { if (index != 0) { // Only the first element can bleed to the top context.RenderArgs.BleedDirection &= ~BleedDirection.BleedUp; } if (index != elements.Count - 1) { // Only the last element can bleed to the bottom context.RenderArgs.BleedDirection &= ~BleedDirection.BleedDown; } index++; // each element has a row FrameworkElement uiElement = context.Render(cardElement); if (uiElement != null) { TagContent tag = null; Grid separator = null; if (cardElement.Separator && uiContainer.Children.Count > 0) { separator = AddSeparator(context, cardElement, uiContainer); } else if (uiContainer.Children.Count > 0) { separator = AddSpacing(context, cardElement, uiContainer); } tag = new TagContent(separator, uiContainer); uiElement.Tag = tag; // Sets the minHeight property for Container and ColumnSet if (cardElement.Type == "Container" || cardElement.Type == "ColumnSet") { AdaptiveCollectionElement collectionElement = (AdaptiveCollectionElement)cardElement; uiElement.MinHeight = collectionElement.PixelMinHeight; } int rowDefinitionIndex = uiContainer.RowDefinitions.Count; RowDefinition rowDefinition = null; if (cardElement.Height != AdaptiveHeight.Stretch) { rowDefinition = new RowDefinition() { Height = GridLength.Auto }; uiContainer.RowDefinitions.Add(rowDefinition); Grid.SetRow(uiElement, rowDefinitionIndex); uiContainer.Children.Add(uiElement); // Row definition is stored in the tag for containers and elements that stretch // so when the elements are shown, the row can have it's original definition, // while when the element is hidden, the extra space is not reserved in the layout tag.RowDefinition = rowDefinition; tag.ViewIndex = rowDefinitionIndex; context.SetVisibility(uiElement, cardElement.IsVisible, tag); } else { rowDefinition = new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }; uiContainer.RowDefinitions.Add(rowDefinition); // Row definition is stored in the tag for containers and elements that stretch // so when the elements are shown, the row can have it's original definition, // while when the element is hidden, the extra space is not reserved in the layout tag.RowDefinition = rowDefinition; tag.ViewIndex = rowDefinitionIndex; if (cardElement.Type == "Container") { Grid.SetRow(uiElement, rowDefinitionIndex); uiContainer.Children.Add(uiElement); context.SetVisibility(uiElement, cardElement.IsVisible, tag); } else { StackPanel panel = new StackPanel(); if (!String.IsNullOrEmpty(cardElement.Id)) { panel.Name = cardElement.Id; } panel.Children.Add(uiElement); panel.Tag = tag; Grid.SetRow(panel, rowDefinitionIndex); uiContainer.Children.Add(panel); context.SetVisibility(panel, cardElement.IsVisible, tag); } } } } context.ResetSeparatorVisibilityInsideContainer(uiContainer); }
private void HandleSeparatorAndSpacing(bool isFirstVisible, FrameworkElement element, TagContent tagContent) { // Hide the spacing / separator for the first element // Separators are added as a grid Grid separator = tagContent.Separator; if (separator != null) { separator.Visibility = isFirstVisible ? Visibility.Collapsed : Visibility.Visible; } else { bool mustHideSpacing = (isFirstVisible && !(tagContent.SpacingHasBeenHidden)); bool mustShowSpacing = (!isFirstVisible && tagContent.SpacingHasBeenHidden); if (mustHideSpacing || mustShowSpacing) { FrameworkElement renderedElement = GetRenderedElement(element); var spacing = Config.GetSpacing(tagContent.Spacing); // The spacings are added as a margin in the top, so we have to deduct that value if (mustHideSpacing) { spacing = -spacing; } Thickness renderedMargin = renderedElement.Margin; renderedElement.Margin = new Thickness(renderedMargin.Left, renderedMargin.Top + spacing, renderedMargin.Right, renderedMargin.Bottom); tagContent.SpacingHasBeenHidden = mustHideSpacing; } } }
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) { TagContent tag = new TagContent(AdaptiveSpacing.None, uiContainer); if (cardElement.Separator && uiContainer.Children.Count > 0) { Grid separator = AddSeparator(context, cardElement, uiContainer); tag = new TagContent(separator, 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); tag = new TagContent(cardElement.Spacing, uiContainer); } uiElement.Tag = tag; if (cardElement.Type == "Container" || cardElement.Type == "ColumnSet") { AdaptiveCollectionElement collectionElement = (AdaptiveCollectionElement)cardElement; uiElement.MinHeight = collectionElement.PixelMinHeight; } if (cardElement.Height != AdaptiveHeight.Stretch) { context.SetVisibility(uiElement, cardElement.IsVisible, tag); uiContainer.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); Grid.SetRow(uiElement, uiContainer.RowDefinitions.Count - 1); uiContainer.Children.Add(uiElement); } else { if (cardElement.Type == "Container") { context.SetVisibility(uiElement, cardElement.IsVisible, tag); 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(); context.SetVisibility(panel, cardElement.IsVisible, tag); if (!String.IsNullOrEmpty(cardElement.Id)) { panel.Name = cardElement.Id; } panel.Children.Add(uiElement); panel.Tag = tag; uiContainer.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); Grid.SetRow(panel, uiContainer.RowDefinitions.Count - 1); uiContainer.Children.Add(panel); } } } } context.ResetSeparatorVisibilityInsideContainer(uiContainer); }