Пример #1
0
        protected virtual void OnLayout(LayoutEventArgs e)
        {
            if (Initialized && !_state[s_stateInLayout])
            {
                _state[s_stateInLayout] = true;
                try
                {
                    Margin           = DefaultMargin;
                    CachedBoundsMode = true;
                    try
                    {
                        // dont layout in the constructor that's just tacky.
                        bool parentNeedsLayout = LayoutEngine.Layout(this, e);
                    }
                    finally
                    {
                        CachedBoundsMode = false;
                    }

                    ToolStripPanelCell cell = RowManager.GetNextVisibleCell(Cells.Count - 1, /*forward*/ false);
                    if (cell is null)
                    {
                        ApplyCachedBounds();
                    }
                    else if (Orientation == Orientation.Horizontal)
                    {
                        OnLayoutHorizontalPostFix();
                    }
                    else
                    {
                        OnLayoutVerticalPostFix();
                    }
                }
                finally
                {
                    _state[s_stateInLayout] = false;
                }
            }
        }
Пример #2
0
        private void OnLayoutVerticalPostFix()
        {
            ToolStripPanelCell cell = RowManager.GetNextVisibleCell(Cells.Count - 1, /*forward*/ false);
            // figure out how much space we actually need to free.
            int spaceToFree = cell.CachedBounds.Bottom - RowManager.DisplayRectangle.Bottom;

            if (spaceToFree <= 0)
            {
                // we're all good. Just apply the cached bounds.
                ApplyCachedBounds();
                return;
            }

            // STEP 1 remove empty space in the row.

            // since layout sisuspended, we'll need to watch changes to the margin
            // as a result of calling FreeSpaceFromRow.
            int[] margins = new int[Cells.Count];
            for (int i = 0; i < Cells.Count; i++)
            {
                ToolStripPanelCell c = Cells[i] as ToolStripPanelCell;
                margins[i] = c.Margin.Top;
            }

            spaceToFree -= RowManager.FreeSpaceFromRow(spaceToFree);

            // now apply those changes to the cached bounds.
            for (int i = 0; i < Cells.Count; i++)
            {
                ToolStripPanelCell c            = Cells[i] as ToolStripPanelCell;
                Rectangle          cachedBounds = c.CachedBounds;
                cachedBounds.X = Math.Max(0, cachedBounds.X - margins[i] - c.Margin.Top);
                c.CachedBounds = cachedBounds;
            }

            if (spaceToFree <= 0)
            {
                ApplyCachedBounds();
                return;
            }

            // STEP 2 change the size of the remaing ToolStrips from Bottom to Top.
            int[] cellOffsets = null;
            for (int i = Cells.Count - 1; i >= 0; i--)
            {
                ToolStripPanelCell currentCell = Cells[i] as ToolStripPanelCell;
                if (currentCell.Visible)
                {
                    Size      minSize      = GetMinimumSize(currentCell.Control as ToolStrip);
                    Rectangle cachedBounds = currentCell.CachedBounds;

                    // found some space to free.
                    if (cachedBounds.Height > minSize.Height)
                    {
                        spaceToFree -= (cachedBounds.Height - minSize.Height);
                        // make sure we dont take more space than we need - if spaceToFree is less than 0, add back in.
                        cachedBounds.Height = (spaceToFree < 0) ? minSize.Height + -spaceToFree : minSize.Height;

                        // we're not reperforming a layout, so we need to adjust the next cell
                        for (int j = i + 1; j < Cells.Count; j++)
                        {
                            if (cellOffsets is null)
                            {
                                cellOffsets = new int[Cells.Count];
                            }

                            cellOffsets[j] += Math.Max(0, currentCell.CachedBounds.Height - cachedBounds.Height);
                        }

                        currentCell.CachedBounds = cachedBounds;
                    }
                }

                if (spaceToFree <= 0)
                {
                    break;
                }
            }

            // fixup for items before it shrinking.
            if (cellOffsets != null)
            {
                for (int i = 0; i < Cells.Count; i++)
                {
                    ToolStripPanelCell c            = Cells[i] as ToolStripPanelCell;
                    Rectangle          cachedBounds = c.CachedBounds;
                    cachedBounds.Y -= cellOffsets[i];
                    c.CachedBounds  = cachedBounds;
                }
            }

            ApplyCachedBounds();
        }