示例#1
0
        private void MakeUIStructure()
        {
            //we go through the children and determine the rows, columns and positions in the grid:
            if (this.HasChildren)
            {
                int  amountOfRows    = 1;         // = 1 for the remaining space
                int  amountOfColumns = 1;         // = 1 for the remaining space
                Dock lastChildDock   = Dock.Left; //We only need it to know the amount of rows and columns and to know which row and column are the "remaining space" (sized at star) in the case where LastChildFill is true.

                //first pass: we count the amount of rows and columns.
                foreach (UIElement child in Children)
                {
                    //get the Dock value of the child:
                    Dock dock = DockPanel.GetDock(child);

                    if (dock == Dock.Left || dock == Dock.Right)
                    {
                        ++amountOfColumns;
                    }
                    else
                    {
                        ++amountOfRows;
                    }
                }
                if (LastChildFill) //if the last child fills the remaining space, we "remove" the row/column we "added" for this child.
                {
                    lastChildDock = GetDock(Children[Children.Count - 1]);
                    if (lastChildDock == Dock.Right || lastChildDock == Dock.Left)
                    {
                        --amountOfColumns;
                    }
                    else
                    {
                        --amountOfRows;
                    }
                }

                //second pass: we determine the Grid.Row, Grid.Column, Grid.RowSpan and Grid.ColumnsSpan for each child.
                int amountOfRightPlaced  = 0;
                int amountOfLeftPlaced   = 0;
                int amountOfTopPlaced    = 0;
                int amountOfBottomPlaced = 0;

                foreach (UIElement child in Children)
                {
                    //get the Dock value of the child:
                    Dock dock = DockPanel.GetDock(child);

                    switch (dock)
                    {
                    case Dock.Left:
                        Grid.SetRow(child, amountOfTopPlaced);
                        Grid.SetColumn(child, amountOfLeftPlaced);
                        Grid.SetRowSpan(child, amountOfRows - amountOfTopPlaced - amountOfBottomPlaced);
                        Grid.SetColumnSpan(child, 1);
                        ++amountOfLeftPlaced;
                        break;

                    case Dock.Top:
                        Grid.SetRow(child, amountOfTopPlaced);
                        Grid.SetColumn(child, amountOfLeftPlaced);
                        Grid.SetRowSpan(child, 1);
                        Grid.SetColumnSpan(child, amountOfColumns - amountOfLeftPlaced - amountOfRightPlaced);
                        ++amountOfTopPlaced;
                        break;

                    case Dock.Right:
                        Grid.SetRow(child, amountOfTopPlaced);
                        Grid.SetColumn(child, amountOfColumns - amountOfRightPlaced - 1);
                        Grid.SetRowSpan(child, amountOfRows - amountOfTopPlaced - amountOfBottomPlaced);
                        Grid.SetColumnSpan(child, 1);
                        ++amountOfRightPlaced;
                        break;

                    case Dock.Bottom:
                        Grid.SetRow(child, amountOfRows - amountOfBottomPlaced - 1);
                        Grid.SetColumn(child, amountOfLeftPlaced);
                        Grid.SetRowSpan(child, 1);
                        Grid.SetColumnSpan(child, amountOfColumns - amountOfLeftPlaced - amountOfRightPlaced);
                        ++amountOfBottomPlaced;
                        break;

                    default:
                        break;
                    }
                }

                //we remove the grid because we will change its structure A LOT, and we want to avoid redrawing everything on each change:
                INTERNAL_VisualTreeManager.DetachVisualChildIfNotNull(_grid, this);

                ColumnDefinitionCollection columnsDefinitions = _grid.ColumnDefinitions;
                columnsDefinitions.Clear();
                for (int i = 0; i < amountOfColumns; ++i)
                {
                    columnsDefinitions.Add(new ColumnDefinition()
                    {
                        Width = GridLength.Auto
                    });
                }
                RowDefinitionCollection rowsDefinitions = _grid.RowDefinitions;
                rowsDefinitions.Clear();
                for (int i = 0; i < amountOfRows; ++i)
                {
                    rowsDefinitions.Add(new RowDefinition()
                    {
                        Height = GridLength.Auto
                    });
                }

                if (!LastChildFill)
                {
                    columnsDefinitions.ElementAt(amountOfLeftPlaced).Width = new GridLength(1, GridUnitType.Star);
                    rowsDefinitions.ElementAt(amountOfTopPlaced).Height    = new GridLength(1, GridUnitType.Star);
                }
                else
                {
                    //the position of the "remaining space" depends on the last child's dock:
                    if (lastChildDock == Dock.Left)
                    {
                        columnsDefinitions.ElementAt(amountOfLeftPlaced - 1).Width = new GridLength(1, GridUnitType.Star); //minus 1 because the column index of the last child placed left is also the column index of the "remaining space".
                    }
                    else
                    {
                        columnsDefinitions.ElementAt(amountOfLeftPlaced).Width = new GridLength(1, GridUnitType.Star);
                    }

                    if (lastChildDock == Dock.Top)
                    {
                        rowsDefinitions.ElementAt(amountOfTopPlaced - 1).Height = new GridLength(1, GridUnitType.Star); //minus 1 because the column index of the last child placed left is also the column index of the "remaining space".
                    }
                    else
                    {
                        rowsDefinitions.ElementAt(amountOfTopPlaced).Height = new GridLength(1, GridUnitType.Star); //minus 1 because the column index of the last child placed left is also the column index of the "remaining space".
                    }
                }
                //the changes on the grid's structure are over so we can put it back.
                INTERNAL_VisualTreeManager.AttachVisualChildIfNotAlreadyAttached(_grid, this);
            }
        }