| File: Layout\AndExpandLayoutManager.cs | Web Access |
| Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls) |
#nullable disable using Microsoft.Maui.Graphics; using Microsoft.Maui.Layouts; namespace Microsoft.Maui.Controls { public class AndExpandLayoutManager : ILayoutManager { IGridLayout _gridLayout; readonly StackLayout _stackLayout; GridLayoutManager _manager; public AndExpandLayoutManager(StackLayout stackLayout) { _stackLayout = stackLayout; } public Size Measure(double widthConstraint, double heightConstraint) { // We have to rebuild this every time because the StackLayout contents // and values may have changed _gridLayout?.Clear(); _gridLayout = Gridify(_stackLayout); _manager = new GridLayoutManager(_gridLayout); return _manager.Measure(widthConstraint, heightConstraint); } public Size ArrangeChildren(Rect bounds) { if (_manager == null) { // This shouldn't really happen, but some compatibility layouts might be // forcing a layout without a measure, so we'll have to ensure measurement happens here Measure(bounds.Width, bounds.Height); } return _manager.ArrangeChildren(bounds); } static IGridLayout Gridify(StackLayout stackLayout) { if (stackLayout.Orientation == StackOrientation.Vertical) { return AndExpandLayoutManager.ConvertToRows(stackLayout); } return AndExpandLayoutManager.ConvertToColumns(stackLayout); } static IGridLayout ConvertToRows(StackLayout stackLayout) { Grid grid = new AndExpandGrid(stackLayout) { ColumnDefinitions = new ColumnDefinitionCollection { new ColumnDefinition { Width = GridLength.Star } }, RowDefinitions = new RowDefinitionCollection(), RowSpacing = stackLayout.Spacing, }; var row = 0; for (int n = 0; n < stackLayout.Count; n++) { var child = stackLayout[n]; if (child.Visibility != Visibility.Visible) { continue; } if (child is View view && view.VerticalOptions.Expands) { grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star }); } else { grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); } grid.Add(child); grid.SetRow(child, row); row += 1; } return grid; } static IGridLayout ConvertToColumns(StackLayout stackLayout) { Grid grid = new AndExpandGrid(stackLayout) { RowDefinitions = new RowDefinitionCollection { new RowDefinition { Height = GridLength.Star } }, ColumnDefinitions = new ColumnDefinitionCollection(), ColumnSpacing = stackLayout.Spacing }; var column = 0; for (int n = 0; n < stackLayout.Count; n++) { var child = stackLayout[n]; if (child.Visibility != Visibility.Visible) { continue; } if (child is View view && view.HorizontalOptions.Expands) { grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star }); } else { grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); } grid.Add(child); grid.SetColumn(child, column); column += 1; } return grid; } class AndExpandGrid : Grid { protected override void OnChildAdded(Element child) { // We don't want to actually re-parent the stuff we add to this } protected override void OnChildRemoved(Element child, int oldLogicalIndex) { // Don't do anything here; the base methods will null out Parents, etc., and we don't want that } public AndExpandGrid(StackLayout layout) { Margin = layout.Margin; Padding = layout.Padding; } } } }