ToolStripPanelRow.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / ToolStripPanelRow.cs / 1305376 / ToolStripPanelRow.cs

                            //#define DEBUG_PAINT 
//------------------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
//  
//-----------------------------------------------------------------------------
/* 
*/ 
namespace System.Windows.Forms {
    using System.Drawing; 
    using System.Windows.Forms.Layout;
    using System.Collections.Specialized;
    using System.Collections;
    using System.ComponentModel; 
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization; 

    ///  
    [ToolboxItem(false)]
    public class ToolStripPanelRow : Component, IArrangedElement {
        private Rectangle bounds = Rectangle.Empty;
        private ToolStripPanel parent = null; 
        private BitVector32 state = new BitVector32();
        private PropertyStore propertyStore = new PropertyStore();  // Contains all properties that are not always set. 
        private int suspendCount = 0; 
        private ToolStripPanelRowManager rowManager = null;
 

        private const int MINALLOWEDWIDTH = 50;
        private const int DragInflateSize = 4;
 
        private static readonly int stateVisible = BitVector32.CreateMask();
        private static readonly int stateDisposing = BitVector32.CreateMask(stateVisible); 
        private static readonly int stateLocked = BitVector32.CreateMask(stateDisposing); 
        private static readonly int stateInitialized = BitVector32.CreateMask(stateLocked);
        private static readonly int stateCachedBoundsMode = BitVector32.CreateMask(stateInitialized); 
        private static readonly int stateInLayout = BitVector32.CreateMask(stateCachedBoundsMode);


 

 
        private static readonly int PropControlsCollection = PropertyStore.CreateKey(); 

#if DEBUG 
        internal static TraceSwitch ToolStripPanelRowCreationDebug = new TraceSwitch("ToolStripPanelRowCreationDebug", "Debug code for rafting row creation");
#else
        internal static TraceSwitch ToolStripPanelRowCreationDebug ;
#endif 

#if DEBUG 
        private static int rowCreationCount = 0; 
        private int thisRowID;
#endif 


        /// 
        public ToolStripPanelRow(ToolStripPanel parent) : this(parent, true){ 
        }
 
 
        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        internal ToolStripPanelRow(ToolStripPanel parent, bool visible) { 
#if DEBUG
            thisRowID = ++rowCreationCount;
#endif
            this.parent = parent; 
            this.state[stateVisible] = visible;
            this.state[stateDisposing | stateLocked| stateInitialized] = false; 
 
            Debug.WriteLineIf(ToolStripPanelRowCreationDebug.TraceVerbose, "Created new ToolStripPanelRow");
 
            using (LayoutTransaction lt = new LayoutTransaction(parent, this, null)) {
                this.Margin = DefaultMargin;
                CommonProperties.SetAutoSize(this, true);
            } 

        } 
 
        /// 
        public Rectangle Bounds { 
            get {
                return bounds;
            }
        } 

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlControlsDescr), SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] 
        public Control[] Controls { 
            get {
                Control[] controls = new Control[ControlsInternal.Count]; 
                ControlsInternal.CopyTo(controls,0);
                return controls;
            }
        } 

 
        ///  
        /// 
        /// Collection of child controls. 
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlControlsDescr)]
        internal ToolStripPanelRowControlCollection ControlsInternal {
            get { 
                ToolStripPanelRowControlCollection controlsCollection = (ToolStripPanelRowControlCollection)Properties.GetObject(PropControlsCollection);
 
                if (controlsCollection == null) { 
                    controlsCollection = CreateControlsInstance();
                    Properties.SetObject(PropControlsCollection, controlsCollection); 
                }

                return controlsCollection;
            } 
        }
 
        internal ArrangedElementCollection Cells { 
            get {
                return ControlsInternal.Cells; 
            }
        }

        internal bool CachedBoundsMode { 
            get {
                return state[stateCachedBoundsMode]; 
            } 
            set {
                state[stateCachedBoundsMode] = value; 
            }
        }

 

        private ToolStripPanelRowManager RowManager { 
            get { 
                if (rowManager == null) {
                    rowManager = (Orientation == Orientation.Horizontal) ? new HorizontalRowManager(this) as ToolStripPanelRowManager 
                                                                         : new VerticalRowManager(this) as ToolStripPanelRowManager;
                    Initialized = true;
                }
 
                return rowManager;
            } 
        } 

        ///  
        protected virtual Padding DefaultMargin {
            get {
                ToolStripPanelCell cell = RowManager.GetNextVisibleCell(0, /*forward*/true);
                if (cell != null && cell.DraggedControl != null) { 
                    if (cell.DraggedControl.Stretch) {
                        Padding padding = ToolStripPanel.RowMargin; 
                        // clear out the padding. 
                        if (Orientation == Orientation.Horizontal) {
                            padding.Left = 0; 
                            padding.Right = 0;
                        }
                        else {
                            padding.Top = 0; 
                            padding.Bottom = 0;
                        } 
                        return padding; 
                    }
                } 
                return ToolStripPanel.RowMargin;

            }
        } 

        ///  
        protected virtual Padding DefaultPadding { 
            get { return Padding.Empty; }
        } 

        /// 
        public Rectangle DisplayRectangle {
            get { 
                return RowManager.DisplayRectangle;
            } 
        } 

        ///  
        public LayoutEngine LayoutEngine {
            get {
                return FlowLayout.Instance;
            } 
        }
 
        ///  
        internal bool Locked {
            get { 
                return state[stateLocked];
            }
        }
 
        /// 
        private bool Initialized { 
            get { 
                return state[stateInitialized];
            } 
            set {
                state[stateInitialized] = value;
            }
        } 

        ///  
        public Padding Margin { 
            get { return CommonProperties.GetMargin(this); }
            set { if (Margin != value ) CommonProperties.SetMargin(this, value); } 
        }

        /// 
        public virtual Padding Padding { 
            get { return CommonProperties.GetPadding(this, DefaultPadding); }
            set { 
                if (Padding != value) CommonProperties.SetPadding(this, value); 
            }
        } 

        internal Control ParentInternal {
            get {
                return parent; 
            }
        } 
 
        /// 
        ///     Retrieves our internal property storage object. If you have a property 
        ///     whose value is not always set, you should store it in here to save
        ///     space.
        /// 
        internal PropertyStore Properties { 
            get {
                return propertyStore; 
            } 
        }
 
        /// 
        public ToolStripPanel ToolStripPanel {
            get {
                return parent; 
            }
        } 
 
        internal bool Visible {
            get { 
                return state[stateVisible];
                }
        }
 
        /// 
        public Orientation Orientation { 
            get { 
                return ToolStripPanel.Orientation;
            } 
        }

#if DEBUG
        internal void Debug_PrintRowID() { 
            Debug.Write(thisRowID.ToString(CultureInfo.CurrentCulture));
        } 
#endif 

        ///  
        /// 
        /// returns true if there is enough space to "raft" the control
        /// ow returns false
        ///  
        public bool CanMove(ToolStrip toolStripToDrag) {
            return !ToolStripPanel.Locked && !Locked && RowManager.CanMove(toolStripToDrag); 
        } 

        ///  
        private ToolStripPanelRowControlCollection CreateControlsInstance() {
            return new ToolStripPanelRowControlCollection(this);
        }
 
        /// 
        protected override void Dispose(bool disposing) { 
            try { 
                if (disposing) {
 
                    Debug.WriteLineIf(ToolStripPanelRowCreationDebug.TraceVerbose, "Disposed ToolStripPanelRow");
                    state[stateDisposing] = true;
                    this.ControlsInternal.Clear();
                } 
            }
            finally { 
                state[stateDisposing] = false; 
                base.Dispose(disposing);
            } 
        }

        /// 
        protected internal virtual void OnControlAdded(Control control, int index) { 

 
            // if previously added - remove. 
            ISupportToolStripPanel controlToBeDragged = control as ISupportToolStripPanel;
 
            if (controlToBeDragged != null) {
                controlToBeDragged.ToolStripPanelRow = this;
            }
            RowManager.OnControlAdded(control, index); 
        }
 
        ///  
        protected internal virtual void OnOrientationChanged() {
            this.rowManager = null; 
        }

        /// 
        protected void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) { 
            ((IArrangedElement)this).PerformLayout((IArrangedElement)this, PropertyNames.Size);
 
            RowManager.OnBoundsChanged(oldBounds,newBounds); 
        }
 
        /// 
        protected internal virtual void OnControlRemoved(Control control, int index) {
            if (!state[stateDisposing]) {
                this.SuspendLayout(); 
                RowManager.OnControlRemoved(control, index);
 
                // if previously added - remove. 
                ISupportToolStripPanel controlToBeDragged = control as ISupportToolStripPanel;
 
 				if (controlToBeDragged != null && controlToBeDragged.ToolStripPanelRow  == this) {
                    controlToBeDragged.ToolStripPanelRow = null;
                }
 
                this.ResumeLayout(true);
                if (this.ControlsInternal.Count <= 0) { 
                    ToolStripPanel.RowsInternal.Remove(this); 
                    Dispose();
                } 
            }
        }

        internal Size GetMinimumSize(ToolStrip toolStrip) { 
            if (toolStrip.MinimumSize == Size.Empty) {
                return new Size(MINALLOWEDWIDTH,MINALLOWEDWIDTH); 
            } 
            else {
                return toolStrip.MinimumSize; 
            }
        }

        private void ApplyCachedBounds() { 
            for (int i = 0; i < this.Cells.Count; i++) {
                IArrangedElement element = Cells[i] as IArrangedElement; 
                if (element.ParticipatesInLayout) { 
                    ToolStripPanelCell cell = element as ToolStripPanelCell;
                    element.SetBounds(cell.CachedBounds, BoundsSpecified.None); 
//                    Debug.Assert( cell.Control == null || cell.CachedBounds.Location == cell.Control.Bounds.Location, "CachedBounds out of [....] with bounds!");
                }
            }
        } 

        ///  
        protected virtual void OnLayout(LayoutEventArgs e) { 
            if (Initialized && !state[stateInLayout]) {
             state[stateInLayout] = true; 
             try {
                    this.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(this.Cells.Count -1, /*forward*/false);
                    if (cell == null) { 
                        ApplyCachedBounds();
                    } 
                    else if (Orientation == Orientation.Horizontal) { 
                        OnLayoutHorizontalPostFix();
                    } 
                    else {
                        OnLayoutVerticalPostFix();
                    }
 
                }
                 finally { 
                    state[stateInLayout] = false; 
                }
            } 
        }


 
        private void OnLayoutHorizontalPostFix() {
 
            ToolStripPanelCell cell = RowManager.GetNextVisibleCell(this.Cells.Count -1, /*forward*/false); 
            if (cell == null) {
                ApplyCachedBounds(); 
                return;
            }
            // figure out how much space we actually need to free.
            int spaceToFree = cell.CachedBounds.Right - RowManager.DisplayRectangle.Right; 

            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.Left; 
            }

            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, margins[i] - c.Margin.Left); 
                c.CachedBounds = cachedBounds;
            }

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

 

            // STEP 2 change the size of the remaing ToolStrips from Right to Left.
            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.Width > minSize.Width) {
                        spaceToFree -= (cachedBounds.Width - minSize.Width);
                        // make sure we dont take more space than we need - if spaceToFree is less than 0, add back in. 
                        cachedBounds.Width =  (spaceToFree < 0) ? minSize.Width + -spaceToFree : minSize.Width;
 
                        // 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 == null) { 
                                cellOffsets = new int[Cells.Count];
                            }
                            cellOffsets[j] += Math.Max(0,currentCell.CachedBounds.Width-cachedBounds.Width);
                        } 
                        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.X -= cellOffsets[i]; 
                   c.CachedBounds = cachedBounds;
               }
            }
 
            ApplyCachedBounds();
 
        } 

 
        private void OnLayoutVerticalPostFix() {

          ToolStripPanelCell cell = RowManager.GetNextVisibleCell(this.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 == 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(); 
 
       }
 
#if DEBUG_PAINT
        internal void PaintColumns(PaintEventArgs e) {
            Graphics g = e.Graphics;
 
            using (Pen pen = new Pen(Color.Green)) {
                g.DrawRectangle(pen, this.DisplayRectangle); 
            } 

            foreach (ToolStripPanelCell c in this.Cells) { 
                Rectangle inner = c.Bounds;
                Rectangle b = LayoutUtils.InflateRect(inner, c.Margin);
                if ((b.Width > 0) && (b.Height > 0)) {
                    using(Brush brush = new System.Drawing.Drawing2D.LinearGradientBrush(b, ProfessionalColors.ButtonSelectedGradientBegin, ProfessionalColors.ButtonSelectedGradientEnd, System.Drawing.Drawing2D.LinearGradientMode.Horizontal)) { 
                        g.FillRectangle(brush, b);
                        g.DrawRectangle(SystemPens.ControlDarkDark, b.X, b.Y, b.Width -1, b.Height -1); 
                        g.DrawRectangle(Pens.HotPink, inner.X, inner.Y, inner.Width -1, inner.Height -1); 
                        if (c.Control != null) {
                            g.DrawString("BAD\r\n" + c.Control.Name, ToolStripPanel.Font, SystemBrushes.ControlText, inner); 
                        }
                        else {
                            g.DrawString("BAD\r\n" + "NULL control", ToolStripPanel.Font, SystemBrushes.ControlText, inner);
 
                        }
                    } 
                } 
            }
        } 
#endif

        private void SetBounds(Rectangle bounds) {
            if (bounds != this.bounds) { 
                Rectangle oldBounds = this.bounds;
 
                this.bounds = bounds; 
                OnBoundsChanged(oldBounds, bounds);
            } 
        }

        private void SuspendLayout() {
            suspendCount++; 
        }
 
        private void ResumeLayout(bool performLayout) { 
            suspendCount--;
            if (performLayout) { 
                ((IArrangedElement)this).PerformLayout(this, null);
            }
        }
 
        /// 
        ///  
        ///  
        /// 
        ArrangedElementCollection IArrangedElement.Children { 
            get {
                return Cells;
            }
        } 

        ///  
        ///  
        /// Should not be exposed as this returns an unexposed type.
        ///  
        /// 
        IArrangedElement IArrangedElement.Container {
            get {
                return this.ToolStripPanel; 
            }
        } 
 
        /// 
        ///  
        ///


        Rectangle IArrangedElement.DisplayRectangle { 
            get {
                Rectangle displayRectangle = this.Bounds; 
 
                return displayRectangle;
            } 
        }

        /// 
        ///  
        ///
 
 
        bool IArrangedElement.ParticipatesInLayout {
            get { 
                return Visible;
            }
        }
 
        /// 
        ///  
        PropertyStore IArrangedElement.Properties { 
            get {
                return this.Properties; 
            }
        }

        ///  
        /// 
        Size IArrangedElement.GetPreferredSize(Size constrainingSize) { 
            Size preferredSize = LayoutEngine.GetPreferredSize(this, constrainingSize - Padding.Size) + Padding.Size; 

            if (Orientation == Orientation.Horizontal && ParentInternal != null) { 
                preferredSize.Width = DisplayRectangle.Width;
            }
            else {
                preferredSize.Height = DisplayRectangle.Height; 
            }
 
            return preferredSize; 
        }
 
        // Sets the bounds for an element.
        /// 
        /// 
        void IArrangedElement.SetBounds(Rectangle bounds, BoundsSpecified specified) { 
            // in this case the parent is telling us to refresh our bounds - dont
            // call PerformLayout 
            SetBounds(bounds); 
        }
 

        /// 
        /// 
        /// 

 
        void IArrangedElement.PerformLayout(IArrangedElement container, string propertyName) { 
            if (suspendCount <= 0) {
                OnLayout(new LayoutEventArgs(container, propertyName)); 
            }
        }

            #region MouseStuff 

#if DEBUG 
      internal static readonly TraceSwitch ToolStripPanelMouseDebug = new TraceSwitch("ToolStripPanelMouse", "Debug WinBar WM_MOUSEACTIVATE code"); 
#else
        internal static readonly TraceSwitch ToolStripPanelMouseDebug; 
#endif


        internal Rectangle DragBounds { 
            get {
                return RowManager.DragBounds; 
            } 
        }
 
        /// 
        internal void MoveControl(ToolStrip movingControl, Point startClientLocation, Point endClientLocation) {
            RowManager.MoveControl(movingControl, startClientLocation, endClientLocation);
        } 

        // 
 

        internal void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) { 
            RowManager.JoinRow(toolStripToDrag, locationToDrag);
        }

        internal void LeaveRow(ToolStrip toolStripToDrag) { 
            RowManager.LeaveRow(toolStripToDrag);
            if (ControlsInternal.Count == 0) { 
                ToolStripPanel.RowsInternal.Remove(this); 
                Dispose();
            } 
        }

        [Conditional("DEBUG")]
        private void PrintPlacements(int index) { 
          /*  Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Results:\r\n\t-------");
            Debug.Indent(); 
            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "ToolStripPanelRow: " + this.Bounds.ToString()); 

            float sumColWidths = 0F; 
            int sumWidths = 0;

            for (int i = 0; i < this.Controls.Count - 1; i++) {
                string indicator = (i == index) ? "*" : " "; 

                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, String.Format("{0} {1} Column Width {2} Control Size {3}", indicator, this.Controls[i].Name, TableLayoutSettings.ColumnStyles[i].Width, this.Controls[i].Bounds)); 
                sumColWidths += TableLayoutSettings.ColumnStyles[i].Width; 
                sumWidths += this.Controls[i].Width;
            } 

            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Total Column Width " + sumColWidths.ToString() + " Total control widths " + sumWidths.ToString());
            Debug.Unindent();
            */ 
        }
            #endregion 
 

        private abstract class ToolStripPanelRowManager { 
            private FlowLayoutSettings flowLayoutSettings = null;

            private ToolStripPanelRow owner = null;
 
            public ToolStripPanelRowManager(ToolStripPanelRow owner) {
                this.owner = owner; 
            } 

            public virtual bool CanMove(ToolStrip toolStripToDrag) { 
                ISupportToolStripPanel raftingControl = toolStripToDrag as ISupportToolStripPanel;
                if (raftingControl != null) {
                   if (raftingControl.Stretch) {
                        Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "TSP RM CanMove returns false - the item moving is stretched."); 
                        return false;
                   } 
                } 
                foreach (Control c in Row.ControlsInternal) {
                     raftingControl = c as ISupportToolStripPanel; 
                     if (raftingControl != null) {
                        if (raftingControl.Stretch) {
                             Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "TSP RM CanMove returns false - the row already contains a stretched item.");
                             return false; 
                        }
                     } 
                } 
                return true;
            } 

            public virtual Rectangle DragBounds {
                get { return Rectangle.Empty; }
            } 

            public virtual Rectangle DisplayRectangle { 
                get { return Rectangle.Empty; } 
            }
 
            public ToolStripPanel ToolStripPanel {
                get { return owner.ToolStripPanel; }
            }
 
            public ToolStripPanelRow Row {
                get { return owner; } 
            } 

            public FlowLayoutSettings FlowLayoutSettings { 
                get {
                    if (flowLayoutSettings == null) {
                        flowLayoutSettings = new FlowLayoutSettings(owner);
                    } 

                    return flowLayoutSettings; 
                } 
            }
 
            protected internal virtual int FreeSpaceFromRow(int spaceToFree) {
                return 0;
            }
 
            protected virtual int Grow(int index, int growBy) {
                int freedSpace = 0; 
                if (index >= 0 && index < Row.ControlsInternal.Count - 1) { 
                    ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                    if (cell.Visible) { 
                        freedSpace = cell.Grow(growBy);
                    }
                }
                return freedSpace; 
            }
 
            public ToolStripPanelCell GetNextVisibleCell(int index, bool forward) { 
                if (forward) {
                    for (int i = index; i < Row.Cells.Count; i++) { 
                        ToolStripPanelCell cell = Row.Cells[i] as ToolStripPanelCell;
                        if ((cell.Visible || (owner.parent.Visible && cell.ControlInDesignMode)) && cell.ToolStripPanelRow == this.owner) {
                            return cell;
                        } 
                    }
                } 
                else { 
                    for (int i = index; i >=0; i--) {
                        ToolStripPanelCell cell = Row.Cells[i] as ToolStripPanelCell; 
                        if ((cell.Visible || (owner.parent.Visible && cell.ControlInDesignMode)) && cell.ToolStripPanelRow == this.owner) {
                            return cell;
                        }
                    } 

                } 
                return null; 

            } 

            /// 
            /// grows all controls after the index to be their preferred size.
            /// reports back how much space was used. 
            /// 
            protected virtual int GrowControlsAfter(int index, int growBy) { 
               if (growBy < 0) { 
                   Debug.Fail("why was a negative number given to growControlsAfter?");
                   return 0; 
               }

               int spaceToFree = growBy;
 
               for (int i = index + 1; i < Row.ControlsInternal.Count; i++) {
                   // grow the n+1 item first if it was previously shrunk. 
                   int freedSpace = Grow(i, spaceToFree); 

                   if (freedSpace >= 0) { 
                       spaceToFree -= freedSpace;
                       if (spaceToFree <= 0) {
                           return growBy;
                       } 
                   }
               } 
 
               return growBy - spaceToFree;
            } 

            /// 
            /// grows all controls before the index to be their preferred size.
            /// reports back how much space was used. 
            /// 
            protected virtual int GrowControlsBefore(int index, int growBy) { 
               if (growBy < 0) { 
                   Debug.Fail("why was a negative number given to growControlsAfter?");
                   return 0; 
               }

               int spaceToFree = growBy;
 
               // grow the n-1 item first if it was previously shrunk.
               for (int i = index - 1; i >= 0; i--) { 
                   spaceToFree -= Grow(i, spaceToFree); 
                   if (spaceToFree <= 0) {
                       return growBy; // we've already gotten all the free space. 
                   }
               }

               return growBy - spaceToFree; 
            }
 
 

            public virtual void MoveControl(ToolStrip movingControl, Point startClientLocation, Point endClientLocation) { 
           //     ToolStripPanel.Join(movingControl, endScreenLocation);
            }
            public virtual void LeaveRow(ToolStrip toolStripToDrag) {
            } 

            public virtual void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) { 
            } 

            protected internal virtual void OnControlAdded(Control c, int index) { 
            }

            protected internal virtual void OnControlRemoved(Control c, int index) {
            } 

            protected internal virtual void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) { 
            } 
        }
 
        private class HorizontalRowManager : ToolStripPanelRowManager {
            private const int DRAG_BOUNDS_INFLATE = 4;

 
            public HorizontalRowManager(ToolStripPanelRow owner): base (owner) {
                owner.SuspendLayout(); 
                FlowLayoutSettings.WrapContents = false; 
                FlowLayoutSettings.FlowDirection = FlowDirection.LeftToRight;
                owner.ResumeLayout(false); 
            }

            public override Rectangle DisplayRectangle {
                get { 
                    Rectangle displayRect = ((IArrangedElement)Row).DisplayRectangle;
 
                    if (ToolStripPanel != null) { 
                        Rectangle raftingDisplayRectangle = ToolStripPanel.DisplayRectangle;
 
                        if ((!ToolStripPanel.Visible || LayoutUtils.IsZeroWidthOrHeight(raftingDisplayRectangle)) && (ToolStripPanel.ParentInternal != null)){

                            // if were layed out before we're visible we have the wrong display rectangle, so we need to calculate it.
                            displayRect.Width = ToolStripPanel.ParentInternal.DisplayRectangle.Width - (ToolStripPanel.Margin.Horizontal + ToolStripPanel.Padding.Horizontal) - Row.Margin.Horizontal; 
                        }
                        else { 
                            displayRect.Width = raftingDisplayRectangle.Width - Row.Margin.Horizontal; 

                        } 
                    }

                    return displayRect;
                } 
            }
 
            public override Rectangle DragBounds { 
                get {
                    Rectangle dragBounds = Row.Bounds; 
                    int index = ToolStripPanel.RowsInternal.IndexOf(Row);

                    if (index > 0) {
                        Rectangle previousRowBounds = ToolStripPanel.RowsInternal[index - 1].Bounds; 
                        int y = previousRowBounds.Y + previousRowBounds.Height - (previousRowBounds.Height >> 2);
 
                        dragBounds.Height += dragBounds.Y - y; 
                        dragBounds.Y = y;
                    } 

                    if (index < ToolStripPanel.RowsInternal.Count - 1) {
                        Rectangle nextRowBounds = ToolStripPanel.RowsInternal[index + 1].Bounds;
 
                        dragBounds.Height += (nextRowBounds.Height >> 2) + Row.Margin.Bottom + ToolStripPanel.RowsInternal[index + 1].Margin.Top;
                    } 
 
                    dragBounds.Width += Row.Margin.Horizontal + ToolStripPanel.Padding.Horizontal +5;
                    dragBounds.X -= Row.Margin.Left + ToolStripPanel.Padding.Left +4; 
                    return dragBounds;
                }
            }
 
            /// 
            ///  returns true if there is enough space to "raft" the control 
            ///  ow returns false 
            /// 
            public override bool CanMove(ToolStrip toolStripToDrag) { 

                if (base.CanMove(toolStripToDrag)) {
                    Size totalSize = Size.Empty;
 
                    for (int i = 0; i < Row.ControlsInternal.Count; i++ ){
                        totalSize += Row.GetMinimumSize(Row.ControlsInternal[i] as ToolStrip); 
                    } 

                    totalSize += Row.GetMinimumSize(toolStripToDrag as ToolStrip); 
                    return totalSize.Width < DisplayRectangle.Width;
                }
                Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "HorizontalRM.CanMove returns false - not enough room");
                return false; 
            }
 
            protected internal override int FreeSpaceFromRow(int spaceToFree) { 
               int requiredSpace = spaceToFree;
               // take a look at the last guy.  if his right edge exceeds 
               // the new bounds, then we should go ahead and push him into view.

               if (spaceToFree > 0){
                   // we should shrink the last guy and then move him. 
                   ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                   if (lastCellOnRow == null) { 
                        return 0; 
                   }
                   Padding cellMargin = lastCellOnRow.Margin; 

                   // only check margin.left as we are only concerned with getting right edge of
                   // the toolstrip into view. (space after the fact doesnt count).
                    if (cellMargin.Left >= spaceToFree) { 
                       cellMargin.Left -= spaceToFree;
                       cellMargin.Right = 0; 
                       spaceToFree = 0; 

                   } 
                   else {
                       spaceToFree -= lastCellOnRow.Margin.Left;
                       cellMargin.Left = 0;
                       cellMargin.Right = 0; 
                   }
                   lastCellOnRow.Margin = cellMargin; 
 
                   // start moving the toolstrips before this guy.
                   spaceToFree -= MoveLeft(Row.Cells.Count -1, spaceToFree); 

                   if (spaceToFree > 0) {
                       spaceToFree -= lastCellOnRow.Shrink(spaceToFree);
                   } 
                }
                return requiredSpace - Math.Max(0,spaceToFree); 
           } 

            public override void MoveControl(ToolStrip movingControl, Point clientStartLocation, Point clientEndLocation) { 
                if (Row.Locked) {
                    return;
                }
 
                if (DragBounds.Contains(clientEndLocation)) {
                    int index = Row.ControlsInternal.IndexOf(movingControl); 
                    int deltaX = clientEndLocation.X - clientStartLocation.X; 

                    if (deltaX < 0) { 
                        // moving to the left
                        MoveLeft(index, deltaX * -1);
                    }
                    else { 
                        MoveRight(index, deltaX);
                    } 
                } 
                else  {
                    base.MoveControl(movingControl, clientStartLocation, clientEndLocation); 
                }
            }

            private int MoveLeft(int index, int spaceToFree) { 

                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft: " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                int freedSpace = 0; 

                Row.SuspendLayout(); 
                try {
                    if (spaceToFree == 0 || index < 0) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Early EXIT - 0 ");
                        return 0; 
                    }
 
 
                    // remove all margins starting from the index.
                    for (int i = index; i >= 0; i--) { 
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        } 
                        int requiredSpace = spaceToFree - freedSpace;
 
                        Padding cellMargin = cell.Margin; 

                        if (cellMargin.Horizontal >= requiredSpace) { 
                            freedSpace += requiredSpace;

                            cellMargin.Left -= requiredSpace;
                            cellMargin.Right = 0; 
                            cell.Margin = cellMargin;
 
                        } 
                        else {
                            freedSpace += cell.Margin.Horizontal; 
                            cellMargin.Left = 0;
                            cellMargin.Right = 0;
                            cell.Margin = cellMargin;
                        } 

                        if (freedSpace >= spaceToFree) { 
                            // add the space we freed to the next guy. 
                            if (index +1 < Row.Cells.Count) {
                                cell = GetNextVisibleCell(index+1, /*forward*/true); 
                                if (cell != null) {
                                    cellMargin = cell.Margin;
                                    cellMargin.Left += spaceToFree;
                                    cell.Margin = cellMargin; 
                                }
                            } 
 
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            return spaceToFree; 
                        }
                    }
                }
                finally { 
                    Row.ResumeLayout(true);
                } 
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture));
                return freedSpace; 
            }

            private int MoveRight(int index, int spaceToFree) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight: " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                int freedSpace = 0; 
                Row.SuspendLayout(); 
                try {
 
                    if (spaceToFree == 0 || index < 0 || index >= Row.ControlsInternal.Count) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Early EXIT - 0 ");
                        return 0;
                    } 

 
                    ToolStripPanelCell cell; 
                    Padding cellMargin;
 
                    // remove all margins after this point in the index.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue;
                        } 
                        int requiredSpace = spaceToFree - freedSpace; 

                        cellMargin = cell.Margin; 

                        if (cellMargin.Horizontal >= requiredSpace) {
                            freedSpace += requiredSpace;
 
                            cellMargin.Left -= requiredSpace;
                            cellMargin.Right = 0; 
                            cell.Margin = cellMargin; 

                        } 
                        else {
                            freedSpace += cell.Margin.Horizontal;
                            cellMargin.Left = 0;
                            cellMargin.Right = 0; 
                            cell.Margin = cellMargin;
                        } 
 
                        break;
                    } 

                    // add in the space at the end of the row.
                    if (Row.Cells.Count > 0 && (spaceToFree > freedSpace)) {
                        ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward*/false); 
                        if (lastCell != null) {
                            freedSpace += DisplayRectangle.Right - lastCell.Bounds.Right; 
                        } 
                        else {
                            freedSpace += DisplayRectangle.Width; 
                        }

                    }
 

                    // set the margin of the control that's moving. 
                    if (spaceToFree <= freedSpace) { 
                        // add the space we freed to the first guy.
                        cell = GetNextVisibleCell(index, /*forward*/true); 
                        if (cell == null) {
                            cell = Row.Cells[index] as ToolStripPanelCell;
                        }
                        Debug.Assert(cell != null, "Dont expect cell to be null here, what's going on?"); 

                        if (cell != null) { 
                            cellMargin = cell.Margin; 
                            cellMargin.Left += spaceToFree;
                            cell.Margin = cellMargin; 
                        }
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                        return spaceToFree;
                    } 

                    // Now start shrinking. 
                    for (int i = index+1; i < Row.Cells.Count; i++) { 
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue;
                        }
                        int requiredSpace = spaceToFree - freedSpace;
                        freedSpace += cell.Shrink(requiredSpace); 

                         if (spaceToFree >= freedSpace) { 
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered (Shrink): " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                            Row.ResumeLayout(true);
                            return spaceToFree; 
                         }

                    }
 
                    if (Row.Cells.Count == 1) {
                        cell = GetNextVisibleCell(index,/*forward*/true); 
                        if (cell != null) { 
                            cellMargin = cell.Margin;
                            cellMargin.Left += freedSpace; 
                            cell.Margin = cellMargin;
                        }
                    }
 
                }
                finally { 
                    Row.ResumeLayout(true); 
                }
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture));

                return freedSpace;
            } 

 
            public override void LeaveRow(ToolStrip toolStripToDrag) { 
                // this code is here to properly add space to the next control when the
                // toolStripToDrag has been removed from the row. 
                Row.SuspendLayout();
                int index = Row.ControlsInternal.IndexOf(toolStripToDrag);
                if (index >= 0) {
                    if (index < Row.ControlsInternal.Count -1 /*not the last one in the row*/) { 
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                        if (cell.Visible) { 
                            int spaceOccupiedByCell = cell.Margin.Horizontal + cell.Bounds.Width; 

                            // add the space occupied by the cell to the next one. 
                            ToolStripPanelCell nextCell = GetNextVisibleCell(index+1, /*forward*/true);
                            if (nextCell != null) {
                                Padding nextCellMargin = nextCell.Margin;
                                nextCellMargin.Left += spaceOccupiedByCell; 
                                nextCell.Margin = nextCellMargin;
                            } 
                        } 
                    }
                    // remove the control from the row. 
                    ((IList)Row.Cells).RemoveAt(index);
                }
                Row.ResumeLayout(true);
            } 

            protected internal override void OnControlAdded(Control control, int index) { 
            } 

            protected internal override void OnControlRemoved(Control control, int index) { 
            }

            public override void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Horizontal JoinRow called " );
                int index; 
 

                if (!Row.ControlsInternal.Contains(toolStripToDrag)) { 
                    Row.SuspendLayout();

                    try {
                         if (Row.ControlsInternal.Count > 0) { 

                            // walk through the columns and determine which column you want to insert into. 
                            for (index = 0; index < Row.Cells.Count; index++) { 
                                ToolStripPanelCell cell = Row.Cells[index] as ToolStripPanelCell;
                                if (!cell.Visible && !cell.ControlInDesignMode) { 
                                    continue;
                                }

                                //  [:   ]  [: x  ] 
                                if (Row.Cells[index].Bounds.Contains(locationToDrag)) {
                                    break; 
                                } 

                                // take into account the following scenarios 
                                //  [:   ]  x [:   ]
                                // x [:  ]    [:   ]
                                if (Row.Cells[index].Bounds.X >= locationToDrag.X) {
                                    break; 
                                }
 
                            } 

                            Control controlToPushAside = Row.ControlsInternal[index]; 
                            // Plop the new control in the midst of the row in question.
                            if (index < Row.ControlsInternal.Count) {
                                Row.ControlsInternal.Insert(index, toolStripToDrag);
                            } 
                            else {
                                Row.ControlsInternal.Add(toolStripToDrag); 
                            } 

                            // since layout is suspended the control may not be set to its preferred size yet 
                            int controlToDragWidth = (toolStripToDrag.AutoSize) ? toolStripToDrag.PreferredSize.Width : toolStripToDrag.Width;


                            // 
                            // now make it look like it belongs in the row.
                            // 
                            // PUSH the controls after it to the right 

                            int requiredSpace = controlToDragWidth; 
                            if (index == 0) {
                                // make sure we account for the left side
                                requiredSpace += locationToDrag.X;
                            } 
                            int freedSpace = 0;
 
                            if (index < Row.ControlsInternal.Count -1) { 
                                ToolStripPanelCell nextCell = (ToolStripPanelCell)Row.Cells[index+1];
                                Padding nextCellMargin =  nextCell.Margin; 

                                // if we've already got the empty space
                                // (available to us via the margin) use that.
                                if (nextCellMargin.Left > requiredSpace) { 
                                    nextCellMargin.Left -= requiredSpace;
                                    nextCell.Margin = nextCellMargin; 
                                    freedSpace = requiredSpace; 
                                }
                                else { 
                                    // otherwise we've got to
                                    // push all controls after this point to the right
                                    // this dumps the extra stuff into the margin of index+1
                                    freedSpace = MoveRight(index+1, requiredSpace - freedSpace); 

                                    // refetch the margin for "index+1" and remove the freed space 
                                    // from it - we want to actually put this to use on the control 
                                    // before this one - we're making room for the control at
                                    // position "index" 
                                    if (freedSpace > 0) {
                                        nextCellMargin =  nextCell.Margin;
                                        nextCellMargin.Left = Math.Max(0, nextCellMargin.Left - freedSpace);
                                        nextCell.Margin = nextCellMargin; 
                                    }
 
                                } 

 
                            }
                            else {
                                // we're adding to the end.
                                ToolStripPanelCell nextCell = GetNextVisibleCell(Row.Cells.Count-2,  /*forward*/false); 
                                ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
 
                                // count the stuff at the end of the row as freed space 
                                if (nextCell != null && lastCell != null) {
                                    Padding lastCellMargin = lastCell.Margin; 
                                    lastCellMargin.Left = Math.Max(0,locationToDrag.X - nextCell.Bounds.Right);
                                    lastCell.Margin = lastCellMargin;
                                    freedSpace=requiredSpace;
                                } 
                            }
 
                            // If we still need more space, then... 
                            // PUSH the controls before it to the left
                            if (freedSpace < requiredSpace && index > 0) { 
                                freedSpace = MoveLeft(index - 1, requiredSpace - freedSpace);
                            }

                            if (index == 0) { 
                                // if the index is zero and there were controls in the row
                                // we need to take care of pushing over the new cell. 
                                if (freedSpace - controlToDragWidth > 0) { 
                                    ToolStripPanelCell newCell = Row.Cells[index] as ToolStripPanelCell;
                                    Padding newCellMargin =  newCell.Margin; 
                                    newCellMargin.Left = freedSpace - controlToDragWidth;
                                    newCell.Margin = newCellMargin;
                                }
                            } 

 
 

                        } 
                        else {

                            // we're adding to the beginning.
                            Row.ControlsInternal.Add(toolStripToDrag); 

#if DEBUG 
                            ISupportToolStripPanel ctg = toolStripToDrag as ISupportToolStripPanel; 
                            ToolStripPanelRow newPanelRow = ctg.ToolStripPanelRow;
                            Debug.Assert(newPanelRow == Row, "we should now be in the new panel row."); 
#endif
                            if (Row.Cells.Count >0 || toolStripToDrag.IsInDesignMode) {
                                // we're adding to the beginning.
                                ToolStripPanelCell cell = GetNextVisibleCell(Row.Cells.Count-1, /*forward*/false); 
                                if (cell == null && toolStripToDrag.IsInDesignMode) {
                                    cell = (ToolStripPanelCell)Row.Cells[Row.Cells.Count-1]; 
                                } 

                                if (cell != null) { 
                                    Padding cellMargin = cell.Margin;
                                    cellMargin.Left = Math.Max(0,locationToDrag.X-Row.Margin.Left);
                                    cell.Margin = cellMargin;
                                } 
                            }
 
 

                        } 
                    }
                    finally {
                        Row.ResumeLayout(true);
                    } 
                }
            } 
 
            protected internal override void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {
               base.OnBoundsChanged(oldBounds, newBounds); 
            }


 
        }
 
        private class VerticalRowManager : ToolStripPanelRowManager { 

            private const int DRAG_BOUNDS_INFLATE = 4; 

            public VerticalRowManager(ToolStripPanelRow owner): base (owner) {
                owner.SuspendLayout();
                FlowLayoutSettings.WrapContents = false; 
                FlowLayoutSettings.FlowDirection = FlowDirection.TopDown;
                owner.ResumeLayout(false); 
            } 

 
            public override Rectangle DisplayRectangle {
                get {
                    Rectangle displayRect = ((IArrangedElement)Row).DisplayRectangle;
 
                    if (ToolStripPanel != null) {
                        Rectangle raftingDisplayRectangle = ToolStripPanel.DisplayRectangle; 
 
                        if ((!ToolStripPanel.Visible || LayoutUtils.IsZeroWidthOrHeight(raftingDisplayRectangle)) && (ToolStripPanel.ParentInternal != null)){
                            // if were layed out before we're visible we have the wrong display rectangle, so we need to calculate it. 
                            displayRect.Height = ToolStripPanel.ParentInternal.DisplayRectangle.Height - (ToolStripPanel.Margin.Vertical + ToolStripPanel.Padding.Vertical) - Row.Margin.Vertical;
                        }
                        else {
                            displayRect.Height = raftingDisplayRectangle.Height - Row.Margin.Vertical; 
                        }
                    } 
 
                    return displayRect;
                } 
            }
            public override Rectangle DragBounds {
                get {
                    Rectangle dragBounds = Row.Bounds; 
                    int index = ToolStripPanel.RowsInternal.IndexOf(Row);
 
                    /// 
                    if (index > 0) {
                        Rectangle previousRowBounds = ToolStripPanel.RowsInternal[index - 1].Bounds; 
                        int x = previousRowBounds.X + previousRowBounds.Width - (previousRowBounds.Width >> 2);

                        dragBounds.Width += dragBounds.X - x;
                        dragBounds.X = x; 
                    }
 
                    if (index < ToolStripPanel.RowsInternal.Count - 1) { 
                        Rectangle nextRowBounds = ToolStripPanel.RowsInternal[index + 1].Bounds;
 
                        dragBounds.Width += (nextRowBounds.Width >> 2) + Row.Margin.Right + ToolStripPanel.RowsInternal[index + 1].Margin.Left;
                    }

                    dragBounds.Height += Row.Margin.Vertical + ToolStripPanel.Padding.Vertical +5; 
                    dragBounds.Y -= Row.Margin.Top+ ToolStripPanel.Padding.Top +4;
 
 
                    return dragBounds;
                } 
            }

            /// 
            ///  returns true if there is enough space to "raft" the control 
            ///  ow returns false
            ///  
            public override bool CanMove(ToolStrip toolStripToDrag) { 

                 if (base.CanMove(toolStripToDrag)) { 
                    Size totalSize = Size.Empty;

                    for (int i = 0; i < Row.ControlsInternal.Count; i++ ){
                        totalSize += Row.GetMinimumSize(Row.ControlsInternal[i] as ToolStrip); 
                    }
 
                    totalSize += Row.GetMinimumSize(toolStripToDrag); 
                    return totalSize.Height < DisplayRectangle.Height;
                } 

                Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "VerticalRM.CanMove returns false - not enough room");
                return false;
            } 
            protected internal override int FreeSpaceFromRow(int spaceToFree) {
                  int requiredSpace = spaceToFree; 
                  // take a look at the last guy.  if his right edge exceeds 
                  // the new bounds, then we should go ahead and push him into view.
 
                  if (spaceToFree > 0){
                      // we should shrink the last guy and then move him.
                      ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                      if (lastCellOnRow == null) { 
                         return 0;
                      } 
                      Padding cellMargin = lastCellOnRow.Margin; 

                      // only check margin.left as we are only concerned with getting right edge of 
                      // the toolstrip into view. (space after the fact doesnt count).
                       if (cellMargin.Top >= spaceToFree) {
                          cellMargin.Top -= spaceToFree;
                          cellMargin.Bottom = 0; 
                          spaceToFree = 0;
 
                      } 
                      else {
                          spaceToFree -= lastCellOnRow.Margin.Top; 
                          cellMargin.Top = 0;
                          cellMargin.Bottom = 0;
                      }
                      lastCellOnRow.Margin = cellMargin; 

                      // start moving the toolstrips before this guy. 
                      spaceToFree -= MoveUp(Row.Cells.Count -1, spaceToFree); 

                      if (spaceToFree > 0) { 
                          spaceToFree -= lastCellOnRow.Shrink(spaceToFree);
                      }
                   }
                   return requiredSpace - Math.Max(0,spaceToFree); 
            }
 
 

            public override void MoveControl(ToolStrip movingControl, Point clientStartLocation, Point clientEndLocation) { 

                if (Row.Locked) {
                    return;
                } 
                if (DragBounds.Contains(clientEndLocation)) {
                   int index = Row.ControlsInternal.IndexOf(movingControl); 
                   int deltaY = clientEndLocation.Y - clientStartLocation.Y; 

                   if (deltaY < 0) { 
                       // moving to the left
                       MoveUp(index, deltaY * -1);
                   }
                   else { 
                       MoveDown(index, deltaY);
                   } 
               } 
               else {
                    base.MoveControl(movingControl, clientStartLocation, clientEndLocation); 
               }
            }

 

            private int MoveUp(int index, int spaceToFree) { 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp: " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                int freedSpace = 0;
 
                Row.SuspendLayout();
                try {
                    if (spaceToFree == 0 || index < 0) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp Early EXIT - 0 "); 
                        return 0;
                    } 
 

                    // remove all margins starting from the index. 
                    for (int i = index; i >= 0; i--) {
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue; 
                        }
                        int requiredSpace = spaceToFree - freedSpace; 
 
                        Padding cellMargin = cell.Margin;
 
                        if (cellMargin.Vertical >= requiredSpace) {
                            freedSpace += requiredSpace;

                            cellMargin.Top -= requiredSpace; 
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin; 
 
                        }
                        else { 
                            freedSpace += cell.Margin.Vertical;
                            cellMargin.Top = 0;
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin; 
                        }
 
                        if (freedSpace >= spaceToFree) { 
                            // add the space we freed to the next guy.
                            if (index +1 < Row.Cells.Count) { 
                                cell = GetNextVisibleCell(index+1, /*forward*/true);
                                if (cell != null) {
                                    cellMargin = cell.Margin;
                                    cellMargin.Top += spaceToFree; 
                                    cell.Margin = cellMargin;
                                } 
                            } 

                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                            return spaceToFree;
                        }
                    }
                } 
                finally {
                    Row.ResumeLayout(true); 
                } 

                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture)); 

                return freedSpace;
            }
 
            private int MoveDown(int index, int spaceToFree) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown: " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                int freedSpace = 0;
                Row.SuspendLayout(); 
                try {

                    if (spaceToFree == 0 || index < 0 || index >= Row.ControlsInternal.Count) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Early EXIT - 0 "); 
                        return 0;
                    } 
 

                    ToolStripPanelCell cell; 
                    Padding cellMargin;

                    // remove all margins after this point in the index.
                    for (int i = index+1; i < Row.Cells.Count; i++) { 
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue; 
                        }
 
                        int requiredSpace = spaceToFree - freedSpace;

                        cellMargin = cell.Margin;
 
                        if (cellMargin.Vertical >= requiredSpace) {
                            freedSpace += requiredSpace; 
 
                            cellMargin.Top -= requiredSpace;
                            cellMargin.Bottom = 0; 
                            cell.Margin = cellMargin;

                        }
                        else { 
                            freedSpace += cell.Margin.Vertical;
                            cellMargin.Top = 0; 
                            cellMargin.Bottom = 0; 
                            cell.Margin = cellMargin;
                        } 

                        break;
                    }
 
                    // add in the space at the end of the row.
                    if (Row.Cells.Count > 0 && (spaceToFree > freedSpace)) { 
                        ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward*/false); 
                        if (lastCell != null) {
                            freedSpace += DisplayRectangle.Bottom - lastCell.Bounds.Bottom; 
                        }
                        else {
                            freedSpace += DisplayRectangle.Height;
                        } 
                    }
 
                    // set the margin of the control that's moving. 
                    if (spaceToFree <= freedSpace) {
                        // add the space we freed to the first guy. 
                        cell = (ToolStripPanelCell)Row.Cells[index];
                        cellMargin = cell.Margin;
                        cellMargin.Top += spaceToFree;
                        cell.Margin = cellMargin; 

                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                        return spaceToFree; 
                    }
 
                    // Now start shrinking.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue;
                        } 
                        int requiredSpace = spaceToFree - freedSpace; 
                        freedSpace += cell.Shrink(requiredSpace);
 
                         if (spaceToFree >= freedSpace) {
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered (Shrink): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            Row.ResumeLayout(true);
                            return spaceToFree; 
                         }
 
                    } 

                    if (Row.Cells.Count == 1) { 
                        cell = GetNextVisibleCell(index,/*forward*/true);
                        if (cell != null) {
                            cellMargin = cell.Margin;
                            cellMargin.Top += freedSpace; 
                            cell.Margin = cellMargin;
                        } 
                    } 

                } 
                finally {
                    Row.ResumeLayout(true);
                }
 
                int recoveredSpace = spaceToFree - freedSpace;
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered Partial (Shrink): " + recoveredSpace.ToString(CultureInfo.InvariantCulture)); 
 
                return recoveredSpace;
            } 

            protected internal override void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {

                base.OnBoundsChanged(oldBounds, newBounds); 

                // if our bounds have changed - we should shove the toolbars up so they're in view. 
                if (Row.Cells.Count > 0) { 

                    // take a look at the last guy.  if his right edge exceeds 
                    // the new bounds, then we should go ahead and push him into view.
                    ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward=*/false);
                    int spaceToFree = (lastCell != null)?  lastCell.Bounds.Bottom - newBounds.Height : 0;
 
                    if (spaceToFree > 0){
                        // we should shrink the last guy and then move him. 
                        ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false); 

                        Padding cellMargin = lastCellOnRow.Margin; 

                        // only check margin.left as we are only concerned with getting bottom edge of
                        // the toolstrip into view. (space after the fact doesnt count).
                         if (cellMargin.Top >= spaceToFree) { 

                            cellMargin.Top -= spaceToFree; 
                            cellMargin.Bottom = 0; 
                            lastCellOnRow.Margin = cellMargin;
                            spaceToFree = 0; 

                        }
                        else {
                            spaceToFree -= lastCellOnRow.Margin.Top; 
                            cellMargin.Top = 0;
                            cellMargin.Bottom = 0; 
                            lastCellOnRow.Margin = cellMargin; 
                        }
                        spaceToFree -= lastCellOnRow.Shrink(spaceToFree); 
                        // start moving the toolstrips before this guy.
                        MoveUp(Row.Cells.Count -1, spaceToFree);
                     }
 
                }
 
            } 

 


            protected internal override void OnControlRemoved(Control c, int index) {
 
            }
 
            protected internal override void OnControlAdded(Control control, int index) { 

            } 


            public override void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Vertical JoinRow called " );
                int index; 
 
                if (!Row.ControlsInternal.Contains(toolStripToDrag)) {
                    Row.SuspendLayout(); 
                    try {
                        if (Row.ControlsInternal.Count > 0) {

 
                            // walk through the columns and determine which column you want to insert into.
                            for (index = 0; index < Row.Cells.Count; index++) { 
                                ToolStripPanelCell cell = Row.Cells[index] as ToolStripPanelCell; 
                                if (!cell.Visible && !cell.ControlInDesignMode) {
                                    continue; 
                                }
                                //  [:   ]  [: x  ]
                                if (cell.Bounds.Contains(locationToDrag)) {
                                    break; 
                                }
 
                                // take into account the following scenarios 
                                //  [:   ]  x [:   ]
                                // x [:  ]    [:   ] 
                                if (cell.Bounds.Y >= locationToDrag.Y) {
                                    break;
                                }
 
                            }
 
                            Control controlToPushAside = Row.ControlsInternal[index]; 
                            // Plop the new control in the midst of the row in question.
                            if (index < Row.ControlsInternal.Count) { 
                                Row.ControlsInternal.Insert(index, toolStripToDrag);
                            }
                            else {
                                Row.ControlsInternal.Add(toolStripToDrag); 
                            }
 
                            // since layout is suspended the control may not be set to its preferred size yet 
                            int controlToDragWidth = (toolStripToDrag.AutoSize) ? toolStripToDrag.PreferredSize.Height : toolStripToDrag.Height;
 
                            //
                            // now make it look like it belongs in the row.
                            //
                            // PUSH the controls after it to the right 

                            int requiredSpace = controlToDragWidth; 
 
                            if (index == 0) {
                                // make sure we account for the left side 
                                requiredSpace += locationToDrag.Y;
                            }
                            int freedSpace = 0;
 
                            if (index < Row.ControlsInternal.Count -1) {
 
                                ToolStripPanelCell nextCell = GetNextVisibleCell(index+1,  /*forward*/true); 
                                if (nextCell != null) {
                                    Padding nextCellMargin =  nextCell.Margin; 

                                    // if we've already got the empty space
                                    // (available to us via the margin) use that.
                                    if (nextCellMargin.Top > requiredSpace) { 
                                        nextCellMargin.Top -= requiredSpace;
                                        nextCell.Margin = nextCellMargin; 
                                        freedSpace = requiredSpace; 
                                    }
                                    else { 
                                        // otherwise we've got to
                                        // push all controls after this point to the right
                                        // this dumps the extra stuff into the margin of index+1
                                        freedSpace = MoveDown(index+1, requiredSpace - freedSpace); 

                                        // refetch the margin for "index+1" and remove the freed space 
                                        // from it - we want to actually put this to use on the control 
                                        // before this one - we're making room for the control at
                                        // position "index" 
                                        if (freedSpace > 0) {
                                            nextCellMargin =  nextCell.Margin;
                                            nextCellMargin.Top -= freedSpace;
                                            nextCell.Margin = nextCellMargin; 
                                        }
 
                                    } 
                                }
 

                            }
                            else {
                                 // we're adding to the end. 
                                ToolStripPanelCell nextCell = GetNextVisibleCell(Row.Cells.Count-2,  /*forward*/false);
                                ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false); 
 
                                // count the stuff at the end of the row as freed space
                                if (nextCell != null && lastCell != null) { 
                                    Padding lastCellMargin =  lastCell.Margin;
                                    lastCellMargin.Top = Math.Max(0,locationToDrag.Y - nextCell.Bounds.Bottom);
                                    lastCell.Margin = lastCellMargin;
                                    freedSpace=requiredSpace; 
                                }
 
                            } 

                            // If we still need more space, then... 
                            // PUSH the controls before it to the left
                            if (freedSpace < requiredSpace && index > 0) {
                                freedSpace = MoveUp(index - 1, requiredSpace - freedSpace);
                            } 

 
                            if (index == 0) { 
                                // if the index is zero and there were controls in the row
                                // we need to take care of pushing over the new cell. 
                                if (freedSpace - controlToDragWidth > 0) {
                                    ToolStripPanelCell newCell = Row.Cells[index] as ToolStripPanelCell;
                                    Padding newCellMargin =  newCell.Margin;
                                    newCellMargin.Top = freedSpace - controlToDragWidth; 
                                    newCell.Margin = newCellMargin;
                                } 
                            } 

                        } 
                        else {

                            // we're adding to the beginning.
                            Row.ControlsInternal.Add(toolStripToDrag); 

#if DEBUG 
                            ISupportToolStripPanel ctg = toolStripToDrag as ISupportToolStripPanel; 
                            ToolStripPanelRow newPanelRow = ctg.ToolStripPanelRow;
                            Debug.Assert(newPanelRow == Row, "we should now be in the new panel row."); 
#endif
                            if (Row.Cells.Count >0) {
                                ToolStripPanelCell cell = GetNextVisibleCell(Row.Cells.Count-1, /*forward*/false);
                                if (cell != null) { 
                                    Padding cellMargin = cell.Margin;
                                    cellMargin.Top = Math.Max(0,locationToDrag.Y-Row.Margin.Top); 
                                    cell.Margin = cellMargin; 
                                }
                            } 
                        }
                    }
                    finally {
                        Row.ResumeLayout(true); 
                    }
                } 
            } 

            public override void LeaveRow(ToolStrip toolStripToDrag) { 
                // this code is here to properly add space to the next control when the
                // toolStripToDrag has been removed from the row.
                Row.SuspendLayout();
                int index = Row.ControlsInternal.IndexOf(toolStripToDrag); 
                if (index >= 0) {
                    if (index < Row.ControlsInternal.Count -1 /*not the last one in the row*/) { 
 
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                        if (cell.Visible) { 
                            int spaceOccupiedByCell = cell.Margin.Vertical + cell.Bounds.Height;

                            // add the space occupied by the cell to the next one.
                            ToolStripPanelCell nextCell = GetNextVisibleCell(index+1, /*forward*/true); 
                            if (nextCell != null) {
                                Padding nextCellMargin = nextCell.Margin; 
                                nextCellMargin.Top += spaceOccupiedByCell; 
                                nextCell.Margin = nextCellMargin;
                            } 
                        }
                    }
                    // remove the control from the row.
                    ((IList)Row.Cells).RemoveAt(index); 
                }
                Row.ResumeLayout(true); 
            } 
        }
 


        /// 
        /// ToolStripPanelRowControlCollection 
        ///
        /// this class represents the collection of controls on a particular row. 
        /// when you add and remove controls from this collection - you also add and remove 
        /// controls to and from the ToolStripPanel.Control's collection (which happens
        /// to be externally readonly.) 
        ///
        /// This class is used to represent the IArrangedElement.Children for the ToolStripPanelRow -
        /// which means that this collection represents the IArrangedElements to layout for
        /// a particular ToolStripPanelRow. 
        ///
        /// We need to keep copies of the controls in both the ToolStripPanelRowControlCollection and 
        /// the ToolStripPanel.Control collection  as the ToolStripPanel.Control collection 
        /// is responsible for parenting and unparenting the controls (ToolStripPanelRows do NOT derive from
        /// Control and thus are NOT hwnd backed). 
        /// 
        /// 
        internal class ToolStripPanelRowControlCollection : ArrangedElementCollection, IList, IEnumerable {
            private ToolStripPanelRow owner; 
            private ArrangedElementCollection cellCollection;
 
            ///  
            public ToolStripPanelRowControlCollection(ToolStripPanelRow owner) {
                this.owner = owner; 
            }


            ///  
            public ToolStripPanelRowControlCollection(ToolStripPanelRow owner, Control[] value) {
                this.owner = owner; 
                AddRange(value); 
            }
 
            /// 
            public new virtual Control this[int index] {
                get {
                    return GetControl(index); 
                }
            } 
 
            public ArrangedElementCollection Cells {
                get { 
                    if (cellCollection == null) {
                        cellCollection = new ArrangedElementCollection(InnerList);
                    }
                    return cellCollection; 
                }
            } 
 

            ///  
            public ToolStripPanel ToolStripPanel {
                get {
                    return owner.ToolStripPanel;
                } 
            }
 
            ///  
            /// 
            /// [To be supplied.] 
            /// 
            [EditorBrowsable(EditorBrowsableState.Never)]
            public int Add(Control value) {
                ISupportToolStripPanel control = value as ISupportToolStripPanel; 

                if (value == null) { 
                    throw new ArgumentNullException("value"); 
                }
                if (control == null) { 
                    throw new NotSupportedException(SR.GetString(SR.TypedControlCollectionShouldBeOfType, typeof(ToolStrip).Name));
                }

                int index = InnerList.Add(control.ToolStripPanelCell); 

                OnAdd(control, index); 
                return index; 
            }
 
            /// 
            /// 
            /// [To be supplied.]
            ///  
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
            [EditorBrowsable(EditorBrowsableState.Never)] 
            public void AddRange(Control[] value) { 
                if (value == null) {
                    throw new ArgumentNullException("value"); 
                }

                ToolStripPanel currentOwner = ToolStripPanel;
 
                if (currentOwner != null) {
                    currentOwner.SuspendLayout(); 
                } 

                try { 
                    for (int i = 0; i < value.Length; i++) {
                        this.Add(value[i]);
                    }
                } 
                finally {
                    if (currentOwner != null) { 
                        currentOwner.ResumeLayout(); 
                    }
                } 
            }

            /// 
            ///  
            /// [To be supplied.]
            ///  
            public bool Contains(Control value) { 
                for (int i = 0; i < Count; i++) {
                    if (GetControl(i) == value) { 
                        return true;
                    }
                }
                return false; 
            }
 
            ///  
            /// 
            /// [To be supplied.] 
            /// 
            public virtual void Clear() {
                if (owner != null) {
                    ToolStripPanel.SuspendLayout(); 
                }
 
                try { 
                    while (Count != 0) {
                        RemoveAt(Count - 1); 
                    }
                }
                finally {
                    if (owner != null) { 
                        ToolStripPanel.ResumeLayout();
                    } 
                } 
            }
 
            public override IEnumerator GetEnumerator() { return new ToolStripPanelCellToControlEnumerator(InnerList); }

            private Control GetControl(int index) {
                Control control = null; 
                ToolStripPanelCell cell = null;
 
                if (index < Count && index >= 0) { 
                    cell  = (ToolStripPanelCell)(InnerList[index]);
                    control = (cell != null) ? cell.Control : null; 
                }
                return control;

            } 
            private int IndexOfControl(Control c) {
                for (int i = 0; i < Count; i++) { 
                    ToolStripPanelCell cell  = (ToolStripPanelCell)(InnerList[i]); 
                    if (cell.Control == c) {
                        return i; 
                    }
                }
                return -1;
 
            }
 
 

 
            void IList.Clear() { Clear(); }

            bool IList.IsFixedSize { get { return InnerList.IsFixedSize; } }
 
            bool IList.Contains(object value) { return InnerList.Contains(value); }
 
            bool IList.IsReadOnly { get { return InnerList.IsReadOnly; } } 

            void IList.RemoveAt(int index) { RemoveAt(index); } 

            void IList.Remove(object value) { Remove(value as Control); }

            int IList.Add(object value) { return Add(value as Control); } 

            int IList.IndexOf(object value) { return IndexOf(value as Control); } 
 
            void IList.Insert(int index, object value) { Insert(index, value as Control); }
 
            /// 
            /// 
            /// [To be supplied.]
            ///  
            public int IndexOf(Control value) {
                for (int i = 0; i < Count; i++) { 
                    if (GetControl(i) == value) { 
                        return i;
                    } 
                }
                return -1;
            }
 
            /// 
            ///  
            /// [To be supplied.] 
            /// 
            [EditorBrowsable(EditorBrowsableState.Never)] 
            public void Insert(int index, Control value) {
                if (value == null) {
                    throw new ArgumentNullException("value");
                } 
                ISupportToolStripPanel control = value as ISupportToolStripPanel;
                if (control == null) { 
                    throw new NotSupportedException(SR.GetString(SR.TypedControlCollectionShouldBeOfType, typeof(ToolStrip).Name)); 
                }
 
                InnerList.Insert(index, control.ToolStripPanelCell);
                OnAdd(control, index);
            }
 
            /// 
            ///  Do proper cleanup of ownership, etc. 
            ///  
            private void OnAfterRemove(Control control, int index) {
                if (owner != null) { 
                    // unfortunately we dont know the index of the control in the ToolStripPanel's
                    // control collection, as all rows share this collection.
                    // To unparent this control we need to use Remove instead  of RemoveAt.
                    using (LayoutTransaction t = new LayoutTransaction(ToolStripPanel, control, PropertyNames.Parent)) { 
                        owner.ToolStripPanel.Controls.Remove(control);
                        owner.OnControlRemoved(control, index); 
                    } 
                }
            } 

            private void OnAdd(ISupportToolStripPanel controlToBeDragged, int index) {
                if (owner != null) {
                    LayoutTransaction layoutTransaction = null; 
                    if (ToolStripPanel != null && ToolStripPanel.ParentInternal != null) {
                        layoutTransaction = new LayoutTransaction(ToolStripPanel, ToolStripPanel.ParentInternal, PropertyNames.Parent); 
 
                    }
                    try { 

                        if (controlToBeDragged != null) {

                            controlToBeDragged.ToolStripPanelRow = owner; 

                            Control control = controlToBeDragged as Control; 
 
                            if (control != null) {
                                control.ParentInternal = owner.ToolStripPanel; 
                                owner.OnControlAdded(control, index);
                            }
                        }
 
                    }
                    finally { 
                        if (layoutTransaction != null) { 
                            layoutTransaction.Dispose();
                        } 
                    }

                }
            } 

            ///  
            ///  
            /// [To be supplied.]
            ///  

            [EditorBrowsable(EditorBrowsableState.Never)]
            public void Remove(Control value) {
                int index = IndexOfControl(value); 
                RemoveAt(index);
            } 
 
            /// 
            ///  
            /// [To be supplied.]
            /// 
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void RemoveAt(int index) { 
                if (index >= 0 && index < Count) {
                    Control control = GetControl(index); 
                    ToolStripPanelCell cell = InnerList[index] as ToolStripPanelCell; 
                    InnerList.RemoveAt(index);
                    OnAfterRemove(control, index); 
                }
            }

            ///  
            /// 
            /// [To be supplied.] 
            ///  
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void CopyTo(Control[] array, int index) { 
                if (array == null) {
                    throw new ArgumentNullException("array");
                }
 
                if (index < 0) {
                    throw new ArgumentOutOfRangeException("index"); 
                } 

                if (index >= array.Length || InnerList.Count > array.Length - index) { 
                    throw new ArgumentException(SR.GetString(SR.ToolStripPanelRowControlCollectionIncorrectIndexLength));
                }

                for (int i = 0; i < InnerList.Count; i++) { 
                    array[index++] = GetControl(i);
                } 
            } 

            /// We want to pretend like we're only holding controls... so everywhere we've returned controls. 
            /// but the problem is if you do a foreach, you'll get the cells not the controls.  So we've got
            /// to sort of write a wrapper class around the ArrayList enumerator.
            private class ToolStripPanelCellToControlEnumerator : IEnumerator, ICloneable {
                private IEnumerator arrayListEnumerator; 

                internal ToolStripPanelCellToControlEnumerator(ArrayList list) { 
                    arrayListEnumerator = ((IEnumerable)list).GetEnumerator(); 
                }
 
                public virtual Object Current {
                    get {
                        ToolStripPanelCell cell = arrayListEnumerator.Current as ToolStripPanelCell;
                        Debug.Assert(cell != null, "Expected ToolStripPanel cells only!!!" + arrayListEnumerator.Current.GetType().ToString()); 
                        return (cell == null) ? null : cell.Control;
                    } 
                } 

 
                public Object Clone() {
                    return MemberwiseClone();
                }
 
                public virtual bool MoveNext() {
                    return arrayListEnumerator.MoveNext(); 
                } 

                public virtual void Reset() { 
                    arrayListEnumerator.Reset();
                }
            }
        } 
    }
} 
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//#define DEBUG_PAINT 
//------------------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
//  
//-----------------------------------------------------------------------------
/* 
*/ 
namespace System.Windows.Forms {
    using System.Drawing; 
    using System.Windows.Forms.Layout;
    using System.Collections.Specialized;
    using System.Collections;
    using System.ComponentModel; 
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization; 

    ///  
    [ToolboxItem(false)]
    public class ToolStripPanelRow : Component, IArrangedElement {
        private Rectangle bounds = Rectangle.Empty;
        private ToolStripPanel parent = null; 
        private BitVector32 state = new BitVector32();
        private PropertyStore propertyStore = new PropertyStore();  // Contains all properties that are not always set. 
        private int suspendCount = 0; 
        private ToolStripPanelRowManager rowManager = null;
 

        private const int MINALLOWEDWIDTH = 50;
        private const int DragInflateSize = 4;
 
        private static readonly int stateVisible = BitVector32.CreateMask();
        private static readonly int stateDisposing = BitVector32.CreateMask(stateVisible); 
        private static readonly int stateLocked = BitVector32.CreateMask(stateDisposing); 
        private static readonly int stateInitialized = BitVector32.CreateMask(stateLocked);
        private static readonly int stateCachedBoundsMode = BitVector32.CreateMask(stateInitialized); 
        private static readonly int stateInLayout = BitVector32.CreateMask(stateCachedBoundsMode);


 

 
        private static readonly int PropControlsCollection = PropertyStore.CreateKey(); 

#if DEBUG 
        internal static TraceSwitch ToolStripPanelRowCreationDebug = new TraceSwitch("ToolStripPanelRowCreationDebug", "Debug code for rafting row creation");
#else
        internal static TraceSwitch ToolStripPanelRowCreationDebug ;
#endif 

#if DEBUG 
        private static int rowCreationCount = 0; 
        private int thisRowID;
#endif 


        /// 
        public ToolStripPanelRow(ToolStripPanel parent) : this(parent, true){ 
        }
 
 
        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        internal ToolStripPanelRow(ToolStripPanel parent, bool visible) { 
#if DEBUG
            thisRowID = ++rowCreationCount;
#endif
            this.parent = parent; 
            this.state[stateVisible] = visible;
            this.state[stateDisposing | stateLocked| stateInitialized] = false; 
 
            Debug.WriteLineIf(ToolStripPanelRowCreationDebug.TraceVerbose, "Created new ToolStripPanelRow");
 
            using (LayoutTransaction lt = new LayoutTransaction(parent, this, null)) {
                this.Margin = DefaultMargin;
                CommonProperties.SetAutoSize(this, true);
            } 

        } 
 
        /// 
        public Rectangle Bounds { 
            get {
                return bounds;
            }
        } 

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlControlsDescr), SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] 
        public Control[] Controls { 
            get {
                Control[] controls = new Control[ControlsInternal.Count]; 
                ControlsInternal.CopyTo(controls,0);
                return controls;
            }
        } 

 
        ///  
        /// 
        /// Collection of child controls. 
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlControlsDescr)]
        internal ToolStripPanelRowControlCollection ControlsInternal {
            get { 
                ToolStripPanelRowControlCollection controlsCollection = (ToolStripPanelRowControlCollection)Properties.GetObject(PropControlsCollection);
 
                if (controlsCollection == null) { 
                    controlsCollection = CreateControlsInstance();
                    Properties.SetObject(PropControlsCollection, controlsCollection); 
                }

                return controlsCollection;
            } 
        }
 
        internal ArrangedElementCollection Cells { 
            get {
                return ControlsInternal.Cells; 
            }
        }

        internal bool CachedBoundsMode { 
            get {
                return state[stateCachedBoundsMode]; 
            } 
            set {
                state[stateCachedBoundsMode] = value; 
            }
        }

 

        private ToolStripPanelRowManager RowManager { 
            get { 
                if (rowManager == null) {
                    rowManager = (Orientation == Orientation.Horizontal) ? new HorizontalRowManager(this) as ToolStripPanelRowManager 
                                                                         : new VerticalRowManager(this) as ToolStripPanelRowManager;
                    Initialized = true;
                }
 
                return rowManager;
            } 
        } 

        ///  
        protected virtual Padding DefaultMargin {
            get {
                ToolStripPanelCell cell = RowManager.GetNextVisibleCell(0, /*forward*/true);
                if (cell != null && cell.DraggedControl != null) { 
                    if (cell.DraggedControl.Stretch) {
                        Padding padding = ToolStripPanel.RowMargin; 
                        // clear out the padding. 
                        if (Orientation == Orientation.Horizontal) {
                            padding.Left = 0; 
                            padding.Right = 0;
                        }
                        else {
                            padding.Top = 0; 
                            padding.Bottom = 0;
                        } 
                        return padding; 
                    }
                } 
                return ToolStripPanel.RowMargin;

            }
        } 

        ///  
        protected virtual Padding DefaultPadding { 
            get { return Padding.Empty; }
        } 

        /// 
        public Rectangle DisplayRectangle {
            get { 
                return RowManager.DisplayRectangle;
            } 
        } 

        ///  
        public LayoutEngine LayoutEngine {
            get {
                return FlowLayout.Instance;
            } 
        }
 
        ///  
        internal bool Locked {
            get { 
                return state[stateLocked];
            }
        }
 
        /// 
        private bool Initialized { 
            get { 
                return state[stateInitialized];
            } 
            set {
                state[stateInitialized] = value;
            }
        } 

        ///  
        public Padding Margin { 
            get { return CommonProperties.GetMargin(this); }
            set { if (Margin != value ) CommonProperties.SetMargin(this, value); } 
        }

        /// 
        public virtual Padding Padding { 
            get { return CommonProperties.GetPadding(this, DefaultPadding); }
            set { 
                if (Padding != value) CommonProperties.SetPadding(this, value); 
            }
        } 

        internal Control ParentInternal {
            get {
                return parent; 
            }
        } 
 
        /// 
        ///     Retrieves our internal property storage object. If you have a property 
        ///     whose value is not always set, you should store it in here to save
        ///     space.
        /// 
        internal PropertyStore Properties { 
            get {
                return propertyStore; 
            } 
        }
 
        /// 
        public ToolStripPanel ToolStripPanel {
            get {
                return parent; 
            }
        } 
 
        internal bool Visible {
            get { 
                return state[stateVisible];
                }
        }
 
        /// 
        public Orientation Orientation { 
            get { 
                return ToolStripPanel.Orientation;
            } 
        }

#if DEBUG
        internal void Debug_PrintRowID() { 
            Debug.Write(thisRowID.ToString(CultureInfo.CurrentCulture));
        } 
#endif 

        ///  
        /// 
        /// returns true if there is enough space to "raft" the control
        /// ow returns false
        ///  
        public bool CanMove(ToolStrip toolStripToDrag) {
            return !ToolStripPanel.Locked && !Locked && RowManager.CanMove(toolStripToDrag); 
        } 

        ///  
        private ToolStripPanelRowControlCollection CreateControlsInstance() {
            return new ToolStripPanelRowControlCollection(this);
        }
 
        /// 
        protected override void Dispose(bool disposing) { 
            try { 
                if (disposing) {
 
                    Debug.WriteLineIf(ToolStripPanelRowCreationDebug.TraceVerbose, "Disposed ToolStripPanelRow");
                    state[stateDisposing] = true;
                    this.ControlsInternal.Clear();
                } 
            }
            finally { 
                state[stateDisposing] = false; 
                base.Dispose(disposing);
            } 
        }

        /// 
        protected internal virtual void OnControlAdded(Control control, int index) { 

 
            // if previously added - remove. 
            ISupportToolStripPanel controlToBeDragged = control as ISupportToolStripPanel;
 
            if (controlToBeDragged != null) {
                controlToBeDragged.ToolStripPanelRow = this;
            }
            RowManager.OnControlAdded(control, index); 
        }
 
        ///  
        protected internal virtual void OnOrientationChanged() {
            this.rowManager = null; 
        }

        /// 
        protected void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) { 
            ((IArrangedElement)this).PerformLayout((IArrangedElement)this, PropertyNames.Size);
 
            RowManager.OnBoundsChanged(oldBounds,newBounds); 
        }
 
        /// 
        protected internal virtual void OnControlRemoved(Control control, int index) {
            if (!state[stateDisposing]) {
                this.SuspendLayout(); 
                RowManager.OnControlRemoved(control, index);
 
                // if previously added - remove. 
                ISupportToolStripPanel controlToBeDragged = control as ISupportToolStripPanel;
 
 				if (controlToBeDragged != null && controlToBeDragged.ToolStripPanelRow  == this) {
                    controlToBeDragged.ToolStripPanelRow = null;
                }
 
                this.ResumeLayout(true);
                if (this.ControlsInternal.Count <= 0) { 
                    ToolStripPanel.RowsInternal.Remove(this); 
                    Dispose();
                } 
            }
        }

        internal Size GetMinimumSize(ToolStrip toolStrip) { 
            if (toolStrip.MinimumSize == Size.Empty) {
                return new Size(MINALLOWEDWIDTH,MINALLOWEDWIDTH); 
            } 
            else {
                return toolStrip.MinimumSize; 
            }
        }

        private void ApplyCachedBounds() { 
            for (int i = 0; i < this.Cells.Count; i++) {
                IArrangedElement element = Cells[i] as IArrangedElement; 
                if (element.ParticipatesInLayout) { 
                    ToolStripPanelCell cell = element as ToolStripPanelCell;
                    element.SetBounds(cell.CachedBounds, BoundsSpecified.None); 
//                    Debug.Assert( cell.Control == null || cell.CachedBounds.Location == cell.Control.Bounds.Location, "CachedBounds out of [....] with bounds!");
                }
            }
        } 

        ///  
        protected virtual void OnLayout(LayoutEventArgs e) { 
            if (Initialized && !state[stateInLayout]) {
             state[stateInLayout] = true; 
             try {
                    this.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(this.Cells.Count -1, /*forward*/false);
                    if (cell == null) { 
                        ApplyCachedBounds();
                    } 
                    else if (Orientation == Orientation.Horizontal) { 
                        OnLayoutHorizontalPostFix();
                    } 
                    else {
                        OnLayoutVerticalPostFix();
                    }
 
                }
                 finally { 
                    state[stateInLayout] = false; 
                }
            } 
        }


 
        private void OnLayoutHorizontalPostFix() {
 
            ToolStripPanelCell cell = RowManager.GetNextVisibleCell(this.Cells.Count -1, /*forward*/false); 
            if (cell == null) {
                ApplyCachedBounds(); 
                return;
            }
            // figure out how much space we actually need to free.
            int spaceToFree = cell.CachedBounds.Right - RowManager.DisplayRectangle.Right; 

            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.Left; 
            }

            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, margins[i] - c.Margin.Left); 
                c.CachedBounds = cachedBounds;
            }

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

 

            // STEP 2 change the size of the remaing ToolStrips from Right to Left.
            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.Width > minSize.Width) {
                        spaceToFree -= (cachedBounds.Width - minSize.Width);
                        // make sure we dont take more space than we need - if spaceToFree is less than 0, add back in. 
                        cachedBounds.Width =  (spaceToFree < 0) ? minSize.Width + -spaceToFree : minSize.Width;
 
                        // 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 == null) { 
                                cellOffsets = new int[Cells.Count];
                            }
                            cellOffsets[j] += Math.Max(0,currentCell.CachedBounds.Width-cachedBounds.Width);
                        } 
                        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.X -= cellOffsets[i]; 
                   c.CachedBounds = cachedBounds;
               }
            }
 
            ApplyCachedBounds();
 
        } 

 
        private void OnLayoutVerticalPostFix() {

          ToolStripPanelCell cell = RowManager.GetNextVisibleCell(this.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 == 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(); 
 
       }
 
#if DEBUG_PAINT
        internal void PaintColumns(PaintEventArgs e) {
            Graphics g = e.Graphics;
 
            using (Pen pen = new Pen(Color.Green)) {
                g.DrawRectangle(pen, this.DisplayRectangle); 
            } 

            foreach (ToolStripPanelCell c in this.Cells) { 
                Rectangle inner = c.Bounds;
                Rectangle b = LayoutUtils.InflateRect(inner, c.Margin);
                if ((b.Width > 0) && (b.Height > 0)) {
                    using(Brush brush = new System.Drawing.Drawing2D.LinearGradientBrush(b, ProfessionalColors.ButtonSelectedGradientBegin, ProfessionalColors.ButtonSelectedGradientEnd, System.Drawing.Drawing2D.LinearGradientMode.Horizontal)) { 
                        g.FillRectangle(brush, b);
                        g.DrawRectangle(SystemPens.ControlDarkDark, b.X, b.Y, b.Width -1, b.Height -1); 
                        g.DrawRectangle(Pens.HotPink, inner.X, inner.Y, inner.Width -1, inner.Height -1); 
                        if (c.Control != null) {
                            g.DrawString("BAD\r\n" + c.Control.Name, ToolStripPanel.Font, SystemBrushes.ControlText, inner); 
                        }
                        else {
                            g.DrawString("BAD\r\n" + "NULL control", ToolStripPanel.Font, SystemBrushes.ControlText, inner);
 
                        }
                    } 
                } 
            }
        } 
#endif

        private void SetBounds(Rectangle bounds) {
            if (bounds != this.bounds) { 
                Rectangle oldBounds = this.bounds;
 
                this.bounds = bounds; 
                OnBoundsChanged(oldBounds, bounds);
            } 
        }

        private void SuspendLayout() {
            suspendCount++; 
        }
 
        private void ResumeLayout(bool performLayout) { 
            suspendCount--;
            if (performLayout) { 
                ((IArrangedElement)this).PerformLayout(this, null);
            }
        }
 
        /// 
        ///  
        ///  
        /// 
        ArrangedElementCollection IArrangedElement.Children { 
            get {
                return Cells;
            }
        } 

        ///  
        ///  
        /// Should not be exposed as this returns an unexposed type.
        ///  
        /// 
        IArrangedElement IArrangedElement.Container {
            get {
                return this.ToolStripPanel; 
            }
        } 
 
        /// 
        ///  
        ///


        Rectangle IArrangedElement.DisplayRectangle { 
            get {
                Rectangle displayRectangle = this.Bounds; 
 
                return displayRectangle;
            } 
        }

        /// 
        ///  
        ///
 
 
        bool IArrangedElement.ParticipatesInLayout {
            get { 
                return Visible;
            }
        }
 
        /// 
        ///  
        PropertyStore IArrangedElement.Properties { 
            get {
                return this.Properties; 
            }
        }

        ///  
        /// 
        Size IArrangedElement.GetPreferredSize(Size constrainingSize) { 
            Size preferredSize = LayoutEngine.GetPreferredSize(this, constrainingSize - Padding.Size) + Padding.Size; 

            if (Orientation == Orientation.Horizontal && ParentInternal != null) { 
                preferredSize.Width = DisplayRectangle.Width;
            }
            else {
                preferredSize.Height = DisplayRectangle.Height; 
            }
 
            return preferredSize; 
        }
 
        // Sets the bounds for an element.
        /// 
        /// 
        void IArrangedElement.SetBounds(Rectangle bounds, BoundsSpecified specified) { 
            // in this case the parent is telling us to refresh our bounds - dont
            // call PerformLayout 
            SetBounds(bounds); 
        }
 

        /// 
        /// 
        /// 

 
        void IArrangedElement.PerformLayout(IArrangedElement container, string propertyName) { 
            if (suspendCount <= 0) {
                OnLayout(new LayoutEventArgs(container, propertyName)); 
            }
        }

            #region MouseStuff 

#if DEBUG 
      internal static readonly TraceSwitch ToolStripPanelMouseDebug = new TraceSwitch("ToolStripPanelMouse", "Debug WinBar WM_MOUSEACTIVATE code"); 
#else
        internal static readonly TraceSwitch ToolStripPanelMouseDebug; 
#endif


        internal Rectangle DragBounds { 
            get {
                return RowManager.DragBounds; 
            } 
        }
 
        /// 
        internal void MoveControl(ToolStrip movingControl, Point startClientLocation, Point endClientLocation) {
            RowManager.MoveControl(movingControl, startClientLocation, endClientLocation);
        } 

        // 
 

        internal void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) { 
            RowManager.JoinRow(toolStripToDrag, locationToDrag);
        }

        internal void LeaveRow(ToolStrip toolStripToDrag) { 
            RowManager.LeaveRow(toolStripToDrag);
            if (ControlsInternal.Count == 0) { 
                ToolStripPanel.RowsInternal.Remove(this); 
                Dispose();
            } 
        }

        [Conditional("DEBUG")]
        private void PrintPlacements(int index) { 
          /*  Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Results:\r\n\t-------");
            Debug.Indent(); 
            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "ToolStripPanelRow: " + this.Bounds.ToString()); 

            float sumColWidths = 0F; 
            int sumWidths = 0;

            for (int i = 0; i < this.Controls.Count - 1; i++) {
                string indicator = (i == index) ? "*" : " "; 

                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, String.Format("{0} {1} Column Width {2} Control Size {3}", indicator, this.Controls[i].Name, TableLayoutSettings.ColumnStyles[i].Width, this.Controls[i].Bounds)); 
                sumColWidths += TableLayoutSettings.ColumnStyles[i].Width; 
                sumWidths += this.Controls[i].Width;
            } 

            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Total Column Width " + sumColWidths.ToString() + " Total control widths " + sumWidths.ToString());
            Debug.Unindent();
            */ 
        }
            #endregion 
 

        private abstract class ToolStripPanelRowManager { 
            private FlowLayoutSettings flowLayoutSettings = null;

            private ToolStripPanelRow owner = null;
 
            public ToolStripPanelRowManager(ToolStripPanelRow owner) {
                this.owner = owner; 
            } 

            public virtual bool CanMove(ToolStrip toolStripToDrag) { 
                ISupportToolStripPanel raftingControl = toolStripToDrag as ISupportToolStripPanel;
                if (raftingControl != null) {
                   if (raftingControl.Stretch) {
                        Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "TSP RM CanMove returns false - the item moving is stretched."); 
                        return false;
                   } 
                } 
                foreach (Control c in Row.ControlsInternal) {
                     raftingControl = c as ISupportToolStripPanel; 
                     if (raftingControl != null) {
                        if (raftingControl.Stretch) {
                             Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "TSP RM CanMove returns false - the row already contains a stretched item.");
                             return false; 
                        }
                     } 
                } 
                return true;
            } 

            public virtual Rectangle DragBounds {
                get { return Rectangle.Empty; }
            } 

            public virtual Rectangle DisplayRectangle { 
                get { return Rectangle.Empty; } 
            }
 
            public ToolStripPanel ToolStripPanel {
                get { return owner.ToolStripPanel; }
            }
 
            public ToolStripPanelRow Row {
                get { return owner; } 
            } 

            public FlowLayoutSettings FlowLayoutSettings { 
                get {
                    if (flowLayoutSettings == null) {
                        flowLayoutSettings = new FlowLayoutSettings(owner);
                    } 

                    return flowLayoutSettings; 
                } 
            }
 
            protected internal virtual int FreeSpaceFromRow(int spaceToFree) {
                return 0;
            }
 
            protected virtual int Grow(int index, int growBy) {
                int freedSpace = 0; 
                if (index >= 0 && index < Row.ControlsInternal.Count - 1) { 
                    ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                    if (cell.Visible) { 
                        freedSpace = cell.Grow(growBy);
                    }
                }
                return freedSpace; 
            }
 
            public ToolStripPanelCell GetNextVisibleCell(int index, bool forward) { 
                if (forward) {
                    for (int i = index; i < Row.Cells.Count; i++) { 
                        ToolStripPanelCell cell = Row.Cells[i] as ToolStripPanelCell;
                        if ((cell.Visible || (owner.parent.Visible && cell.ControlInDesignMode)) && cell.ToolStripPanelRow == this.owner) {
                            return cell;
                        } 
                    }
                } 
                else { 
                    for (int i = index; i >=0; i--) {
                        ToolStripPanelCell cell = Row.Cells[i] as ToolStripPanelCell; 
                        if ((cell.Visible || (owner.parent.Visible && cell.ControlInDesignMode)) && cell.ToolStripPanelRow == this.owner) {
                            return cell;
                        }
                    } 

                } 
                return null; 

            } 

            /// 
            /// grows all controls after the index to be their preferred size.
            /// reports back how much space was used. 
            /// 
            protected virtual int GrowControlsAfter(int index, int growBy) { 
               if (growBy < 0) { 
                   Debug.Fail("why was a negative number given to growControlsAfter?");
                   return 0; 
               }

               int spaceToFree = growBy;
 
               for (int i = index + 1; i < Row.ControlsInternal.Count; i++) {
                   // grow the n+1 item first if it was previously shrunk. 
                   int freedSpace = Grow(i, spaceToFree); 

                   if (freedSpace >= 0) { 
                       spaceToFree -= freedSpace;
                       if (spaceToFree <= 0) {
                           return growBy;
                       } 
                   }
               } 
 
               return growBy - spaceToFree;
            } 

            /// 
            /// grows all controls before the index to be their preferred size.
            /// reports back how much space was used. 
            /// 
            protected virtual int GrowControlsBefore(int index, int growBy) { 
               if (growBy < 0) { 
                   Debug.Fail("why was a negative number given to growControlsAfter?");
                   return 0; 
               }

               int spaceToFree = growBy;
 
               // grow the n-1 item first if it was previously shrunk.
               for (int i = index - 1; i >= 0; i--) { 
                   spaceToFree -= Grow(i, spaceToFree); 
                   if (spaceToFree <= 0) {
                       return growBy; // we've already gotten all the free space. 
                   }
               }

               return growBy - spaceToFree; 
            }
 
 

            public virtual void MoveControl(ToolStrip movingControl, Point startClientLocation, Point endClientLocation) { 
           //     ToolStripPanel.Join(movingControl, endScreenLocation);
            }
            public virtual void LeaveRow(ToolStrip toolStripToDrag) {
            } 

            public virtual void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) { 
            } 

            protected internal virtual void OnControlAdded(Control c, int index) { 
            }

            protected internal virtual void OnControlRemoved(Control c, int index) {
            } 

            protected internal virtual void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) { 
            } 
        }
 
        private class HorizontalRowManager : ToolStripPanelRowManager {
            private const int DRAG_BOUNDS_INFLATE = 4;

 
            public HorizontalRowManager(ToolStripPanelRow owner): base (owner) {
                owner.SuspendLayout(); 
                FlowLayoutSettings.WrapContents = false; 
                FlowLayoutSettings.FlowDirection = FlowDirection.LeftToRight;
                owner.ResumeLayout(false); 
            }

            public override Rectangle DisplayRectangle {
                get { 
                    Rectangle displayRect = ((IArrangedElement)Row).DisplayRectangle;
 
                    if (ToolStripPanel != null) { 
                        Rectangle raftingDisplayRectangle = ToolStripPanel.DisplayRectangle;
 
                        if ((!ToolStripPanel.Visible || LayoutUtils.IsZeroWidthOrHeight(raftingDisplayRectangle)) && (ToolStripPanel.ParentInternal != null)){

                            // if were layed out before we're visible we have the wrong display rectangle, so we need to calculate it.
                            displayRect.Width = ToolStripPanel.ParentInternal.DisplayRectangle.Width - (ToolStripPanel.Margin.Horizontal + ToolStripPanel.Padding.Horizontal) - Row.Margin.Horizontal; 
                        }
                        else { 
                            displayRect.Width = raftingDisplayRectangle.Width - Row.Margin.Horizontal; 

                        } 
                    }

                    return displayRect;
                } 
            }
 
            public override Rectangle DragBounds { 
                get {
                    Rectangle dragBounds = Row.Bounds; 
                    int index = ToolStripPanel.RowsInternal.IndexOf(Row);

                    if (index > 0) {
                        Rectangle previousRowBounds = ToolStripPanel.RowsInternal[index - 1].Bounds; 
                        int y = previousRowBounds.Y + previousRowBounds.Height - (previousRowBounds.Height >> 2);
 
                        dragBounds.Height += dragBounds.Y - y; 
                        dragBounds.Y = y;
                    } 

                    if (index < ToolStripPanel.RowsInternal.Count - 1) {
                        Rectangle nextRowBounds = ToolStripPanel.RowsInternal[index + 1].Bounds;
 
                        dragBounds.Height += (nextRowBounds.Height >> 2) + Row.Margin.Bottom + ToolStripPanel.RowsInternal[index + 1].Margin.Top;
                    } 
 
                    dragBounds.Width += Row.Margin.Horizontal + ToolStripPanel.Padding.Horizontal +5;
                    dragBounds.X -= Row.Margin.Left + ToolStripPanel.Padding.Left +4; 
                    return dragBounds;
                }
            }
 
            /// 
            ///  returns true if there is enough space to "raft" the control 
            ///  ow returns false 
            /// 
            public override bool CanMove(ToolStrip toolStripToDrag) { 

                if (base.CanMove(toolStripToDrag)) {
                    Size totalSize = Size.Empty;
 
                    for (int i = 0; i < Row.ControlsInternal.Count; i++ ){
                        totalSize += Row.GetMinimumSize(Row.ControlsInternal[i] as ToolStrip); 
                    } 

                    totalSize += Row.GetMinimumSize(toolStripToDrag as ToolStrip); 
                    return totalSize.Width < DisplayRectangle.Width;
                }
                Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "HorizontalRM.CanMove returns false - not enough room");
                return false; 
            }
 
            protected internal override int FreeSpaceFromRow(int spaceToFree) { 
               int requiredSpace = spaceToFree;
               // take a look at the last guy.  if his right edge exceeds 
               // the new bounds, then we should go ahead and push him into view.

               if (spaceToFree > 0){
                   // we should shrink the last guy and then move him. 
                   ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                   if (lastCellOnRow == null) { 
                        return 0; 
                   }
                   Padding cellMargin = lastCellOnRow.Margin; 

                   // only check margin.left as we are only concerned with getting right edge of
                   // the toolstrip into view. (space after the fact doesnt count).
                    if (cellMargin.Left >= spaceToFree) { 
                       cellMargin.Left -= spaceToFree;
                       cellMargin.Right = 0; 
                       spaceToFree = 0; 

                   } 
                   else {
                       spaceToFree -= lastCellOnRow.Margin.Left;
                       cellMargin.Left = 0;
                       cellMargin.Right = 0; 
                   }
                   lastCellOnRow.Margin = cellMargin; 
 
                   // start moving the toolstrips before this guy.
                   spaceToFree -= MoveLeft(Row.Cells.Count -1, spaceToFree); 

                   if (spaceToFree > 0) {
                       spaceToFree -= lastCellOnRow.Shrink(spaceToFree);
                   } 
                }
                return requiredSpace - Math.Max(0,spaceToFree); 
           } 

            public override void MoveControl(ToolStrip movingControl, Point clientStartLocation, Point clientEndLocation) { 
                if (Row.Locked) {
                    return;
                }
 
                if (DragBounds.Contains(clientEndLocation)) {
                    int index = Row.ControlsInternal.IndexOf(movingControl); 
                    int deltaX = clientEndLocation.X - clientStartLocation.X; 

                    if (deltaX < 0) { 
                        // moving to the left
                        MoveLeft(index, deltaX * -1);
                    }
                    else { 
                        MoveRight(index, deltaX);
                    } 
                } 
                else  {
                    base.MoveControl(movingControl, clientStartLocation, clientEndLocation); 
                }
            }

            private int MoveLeft(int index, int spaceToFree) { 

                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft: " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                int freedSpace = 0; 

                Row.SuspendLayout(); 
                try {
                    if (spaceToFree == 0 || index < 0) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Early EXIT - 0 ");
                        return 0; 
                    }
 
 
                    // remove all margins starting from the index.
                    for (int i = index; i >= 0; i--) { 
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue;
                        } 
                        int requiredSpace = spaceToFree - freedSpace;
 
                        Padding cellMargin = cell.Margin; 

                        if (cellMargin.Horizontal >= requiredSpace) { 
                            freedSpace += requiredSpace;

                            cellMargin.Left -= requiredSpace;
                            cellMargin.Right = 0; 
                            cell.Margin = cellMargin;
 
                        } 
                        else {
                            freedSpace += cell.Margin.Horizontal; 
                            cellMargin.Left = 0;
                            cellMargin.Right = 0;
                            cell.Margin = cellMargin;
                        } 

                        if (freedSpace >= spaceToFree) { 
                            // add the space we freed to the next guy. 
                            if (index +1 < Row.Cells.Count) {
                                cell = GetNextVisibleCell(index+1, /*forward*/true); 
                                if (cell != null) {
                                    cellMargin = cell.Margin;
                                    cellMargin.Left += spaceToFree;
                                    cell.Margin = cellMargin; 
                                }
                            } 
 
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            return spaceToFree; 
                        }
                    }
                }
                finally { 
                    Row.ResumeLayout(true);
                } 
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture));
                return freedSpace; 
            }

            private int MoveRight(int index, int spaceToFree) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight: " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                int freedSpace = 0; 
                Row.SuspendLayout(); 
                try {
 
                    if (spaceToFree == 0 || index < 0 || index >= Row.ControlsInternal.Count) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Early EXIT - 0 ");
                        return 0;
                    } 

 
                    ToolStripPanelCell cell; 
                    Padding cellMargin;
 
                    // remove all margins after this point in the index.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue;
                        } 
                        int requiredSpace = spaceToFree - freedSpace; 

                        cellMargin = cell.Margin; 

                        if (cellMargin.Horizontal >= requiredSpace) {
                            freedSpace += requiredSpace;
 
                            cellMargin.Left -= requiredSpace;
                            cellMargin.Right = 0; 
                            cell.Margin = cellMargin; 

                        } 
                        else {
                            freedSpace += cell.Margin.Horizontal;
                            cellMargin.Left = 0;
                            cellMargin.Right = 0; 
                            cell.Margin = cellMargin;
                        } 
 
                        break;
                    } 

                    // add in the space at the end of the row.
                    if (Row.Cells.Count > 0 && (spaceToFree > freedSpace)) {
                        ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward*/false); 
                        if (lastCell != null) {
                            freedSpace += DisplayRectangle.Right - lastCell.Bounds.Right; 
                        } 
                        else {
                            freedSpace += DisplayRectangle.Width; 
                        }

                    }
 

                    // set the margin of the control that's moving. 
                    if (spaceToFree <= freedSpace) { 
                        // add the space we freed to the first guy.
                        cell = GetNextVisibleCell(index, /*forward*/true); 
                        if (cell == null) {
                            cell = Row.Cells[index] as ToolStripPanelCell;
                        }
                        Debug.Assert(cell != null, "Dont expect cell to be null here, what's going on?"); 

                        if (cell != null) { 
                            cellMargin = cell.Margin; 
                            cellMargin.Left += spaceToFree;
                            cell.Margin = cellMargin; 
                        }
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                        return spaceToFree;
                    } 

                    // Now start shrinking. 
                    for (int i = index+1; i < Row.Cells.Count; i++) { 
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue;
                        }
                        int requiredSpace = spaceToFree - freedSpace;
                        freedSpace += cell.Shrink(requiredSpace); 

                         if (spaceToFree >= freedSpace) { 
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered (Shrink): " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                            Row.ResumeLayout(true);
                            return spaceToFree; 
                         }

                    }
 
                    if (Row.Cells.Count == 1) {
                        cell = GetNextVisibleCell(index,/*forward*/true); 
                        if (cell != null) { 
                            cellMargin = cell.Margin;
                            cellMargin.Left += freedSpace; 
                            cell.Margin = cellMargin;
                        }
                    }
 
                }
                finally { 
                    Row.ResumeLayout(true); 
                }
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveRight Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture));

                return freedSpace;
            } 

 
            public override void LeaveRow(ToolStrip toolStripToDrag) { 
                // this code is here to properly add space to the next control when the
                // toolStripToDrag has been removed from the row. 
                Row.SuspendLayout();
                int index = Row.ControlsInternal.IndexOf(toolStripToDrag);
                if (index >= 0) {
                    if (index < Row.ControlsInternal.Count -1 /*not the last one in the row*/) { 
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                        if (cell.Visible) { 
                            int spaceOccupiedByCell = cell.Margin.Horizontal + cell.Bounds.Width; 

                            // add the space occupied by the cell to the next one. 
                            ToolStripPanelCell nextCell = GetNextVisibleCell(index+1, /*forward*/true);
                            if (nextCell != null) {
                                Padding nextCellMargin = nextCell.Margin;
                                nextCellMargin.Left += spaceOccupiedByCell; 
                                nextCell.Margin = nextCellMargin;
                            } 
                        } 
                    }
                    // remove the control from the row. 
                    ((IList)Row.Cells).RemoveAt(index);
                }
                Row.ResumeLayout(true);
            } 

            protected internal override void OnControlAdded(Control control, int index) { 
            } 

            protected internal override void OnControlRemoved(Control control, int index) { 
            }

            public override void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Horizontal JoinRow called " );
                int index; 
 

                if (!Row.ControlsInternal.Contains(toolStripToDrag)) { 
                    Row.SuspendLayout();

                    try {
                         if (Row.ControlsInternal.Count > 0) { 

                            // walk through the columns and determine which column you want to insert into. 
                            for (index = 0; index < Row.Cells.Count; index++) { 
                                ToolStripPanelCell cell = Row.Cells[index] as ToolStripPanelCell;
                                if (!cell.Visible && !cell.ControlInDesignMode) { 
                                    continue;
                                }

                                //  [:   ]  [: x  ] 
                                if (Row.Cells[index].Bounds.Contains(locationToDrag)) {
                                    break; 
                                } 

                                // take into account the following scenarios 
                                //  [:   ]  x [:   ]
                                // x [:  ]    [:   ]
                                if (Row.Cells[index].Bounds.X >= locationToDrag.X) {
                                    break; 
                                }
 
                            } 

                            Control controlToPushAside = Row.ControlsInternal[index]; 
                            // Plop the new control in the midst of the row in question.
                            if (index < Row.ControlsInternal.Count) {
                                Row.ControlsInternal.Insert(index, toolStripToDrag);
                            } 
                            else {
                                Row.ControlsInternal.Add(toolStripToDrag); 
                            } 

                            // since layout is suspended the control may not be set to its preferred size yet 
                            int controlToDragWidth = (toolStripToDrag.AutoSize) ? toolStripToDrag.PreferredSize.Width : toolStripToDrag.Width;


                            // 
                            // now make it look like it belongs in the row.
                            // 
                            // PUSH the controls after it to the right 

                            int requiredSpace = controlToDragWidth; 
                            if (index == 0) {
                                // make sure we account for the left side
                                requiredSpace += locationToDrag.X;
                            } 
                            int freedSpace = 0;
 
                            if (index < Row.ControlsInternal.Count -1) { 
                                ToolStripPanelCell nextCell = (ToolStripPanelCell)Row.Cells[index+1];
                                Padding nextCellMargin =  nextCell.Margin; 

                                // if we've already got the empty space
                                // (available to us via the margin) use that.
                                if (nextCellMargin.Left > requiredSpace) { 
                                    nextCellMargin.Left -= requiredSpace;
                                    nextCell.Margin = nextCellMargin; 
                                    freedSpace = requiredSpace; 
                                }
                                else { 
                                    // otherwise we've got to
                                    // push all controls after this point to the right
                                    // this dumps the extra stuff into the margin of index+1
                                    freedSpace = MoveRight(index+1, requiredSpace - freedSpace); 

                                    // refetch the margin for "index+1" and remove the freed space 
                                    // from it - we want to actually put this to use on the control 
                                    // before this one - we're making room for the control at
                                    // position "index" 
                                    if (freedSpace > 0) {
                                        nextCellMargin =  nextCell.Margin;
                                        nextCellMargin.Left = Math.Max(0, nextCellMargin.Left - freedSpace);
                                        nextCell.Margin = nextCellMargin; 
                                    }
 
                                } 

 
                            }
                            else {
                                // we're adding to the end.
                                ToolStripPanelCell nextCell = GetNextVisibleCell(Row.Cells.Count-2,  /*forward*/false); 
                                ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
 
                                // count the stuff at the end of the row as freed space 
                                if (nextCell != null && lastCell != null) {
                                    Padding lastCellMargin = lastCell.Margin; 
                                    lastCellMargin.Left = Math.Max(0,locationToDrag.X - nextCell.Bounds.Right);
                                    lastCell.Margin = lastCellMargin;
                                    freedSpace=requiredSpace;
                                } 
                            }
 
                            // If we still need more space, then... 
                            // PUSH the controls before it to the left
                            if (freedSpace < requiredSpace && index > 0) { 
                                freedSpace = MoveLeft(index - 1, requiredSpace - freedSpace);
                            }

                            if (index == 0) { 
                                // if the index is zero and there were controls in the row
                                // we need to take care of pushing over the new cell. 
                                if (freedSpace - controlToDragWidth > 0) { 
                                    ToolStripPanelCell newCell = Row.Cells[index] as ToolStripPanelCell;
                                    Padding newCellMargin =  newCell.Margin; 
                                    newCellMargin.Left = freedSpace - controlToDragWidth;
                                    newCell.Margin = newCellMargin;
                                }
                            } 

 
 

                        } 
                        else {

                            // we're adding to the beginning.
                            Row.ControlsInternal.Add(toolStripToDrag); 

#if DEBUG 
                            ISupportToolStripPanel ctg = toolStripToDrag as ISupportToolStripPanel; 
                            ToolStripPanelRow newPanelRow = ctg.ToolStripPanelRow;
                            Debug.Assert(newPanelRow == Row, "we should now be in the new panel row."); 
#endif
                            if (Row.Cells.Count >0 || toolStripToDrag.IsInDesignMode) {
                                // we're adding to the beginning.
                                ToolStripPanelCell cell = GetNextVisibleCell(Row.Cells.Count-1, /*forward*/false); 
                                if (cell == null && toolStripToDrag.IsInDesignMode) {
                                    cell = (ToolStripPanelCell)Row.Cells[Row.Cells.Count-1]; 
                                } 

                                if (cell != null) { 
                                    Padding cellMargin = cell.Margin;
                                    cellMargin.Left = Math.Max(0,locationToDrag.X-Row.Margin.Left);
                                    cell.Margin = cellMargin;
                                } 
                            }
 
 

                        } 
                    }
                    finally {
                        Row.ResumeLayout(true);
                    } 
                }
            } 
 
            protected internal override void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {
               base.OnBoundsChanged(oldBounds, newBounds); 
            }


 
        }
 
        private class VerticalRowManager : ToolStripPanelRowManager { 

            private const int DRAG_BOUNDS_INFLATE = 4; 

            public VerticalRowManager(ToolStripPanelRow owner): base (owner) {
                owner.SuspendLayout();
                FlowLayoutSettings.WrapContents = false; 
                FlowLayoutSettings.FlowDirection = FlowDirection.TopDown;
                owner.ResumeLayout(false); 
            } 

 
            public override Rectangle DisplayRectangle {
                get {
                    Rectangle displayRect = ((IArrangedElement)Row).DisplayRectangle;
 
                    if (ToolStripPanel != null) {
                        Rectangle raftingDisplayRectangle = ToolStripPanel.DisplayRectangle; 
 
                        if ((!ToolStripPanel.Visible || LayoutUtils.IsZeroWidthOrHeight(raftingDisplayRectangle)) && (ToolStripPanel.ParentInternal != null)){
                            // if were layed out before we're visible we have the wrong display rectangle, so we need to calculate it. 
                            displayRect.Height = ToolStripPanel.ParentInternal.DisplayRectangle.Height - (ToolStripPanel.Margin.Vertical + ToolStripPanel.Padding.Vertical) - Row.Margin.Vertical;
                        }
                        else {
                            displayRect.Height = raftingDisplayRectangle.Height - Row.Margin.Vertical; 
                        }
                    } 
 
                    return displayRect;
                } 
            }
            public override Rectangle DragBounds {
                get {
                    Rectangle dragBounds = Row.Bounds; 
                    int index = ToolStripPanel.RowsInternal.IndexOf(Row);
 
                    /// 
                    if (index > 0) {
                        Rectangle previousRowBounds = ToolStripPanel.RowsInternal[index - 1].Bounds; 
                        int x = previousRowBounds.X + previousRowBounds.Width - (previousRowBounds.Width >> 2);

                        dragBounds.Width += dragBounds.X - x;
                        dragBounds.X = x; 
                    }
 
                    if (index < ToolStripPanel.RowsInternal.Count - 1) { 
                        Rectangle nextRowBounds = ToolStripPanel.RowsInternal[index + 1].Bounds;
 
                        dragBounds.Width += (nextRowBounds.Width >> 2) + Row.Margin.Right + ToolStripPanel.RowsInternal[index + 1].Margin.Left;
                    }

                    dragBounds.Height += Row.Margin.Vertical + ToolStripPanel.Padding.Vertical +5; 
                    dragBounds.Y -= Row.Margin.Top+ ToolStripPanel.Padding.Top +4;
 
 
                    return dragBounds;
                } 
            }

            /// 
            ///  returns true if there is enough space to "raft" the control 
            ///  ow returns false
            ///  
            public override bool CanMove(ToolStrip toolStripToDrag) { 

                 if (base.CanMove(toolStripToDrag)) { 
                    Size totalSize = Size.Empty;

                    for (int i = 0; i < Row.ControlsInternal.Count; i++ ){
                        totalSize += Row.GetMinimumSize(Row.ControlsInternal[i] as ToolStrip); 
                    }
 
                    totalSize += Row.GetMinimumSize(toolStripToDrag); 
                    return totalSize.Height < DisplayRectangle.Height;
                } 

                Debug.WriteLineIf(ToolStripPanelRow.ToolStripPanelRowCreationDebug.TraceVerbose, "VerticalRM.CanMove returns false - not enough room");
                return false;
            } 
            protected internal override int FreeSpaceFromRow(int spaceToFree) {
                  int requiredSpace = spaceToFree; 
                  // take a look at the last guy.  if his right edge exceeds 
                  // the new bounds, then we should go ahead and push him into view.
 
                  if (spaceToFree > 0){
                      // we should shrink the last guy and then move him.
                      ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false);
                      if (lastCellOnRow == null) { 
                         return 0;
                      } 
                      Padding cellMargin = lastCellOnRow.Margin; 

                      // only check margin.left as we are only concerned with getting right edge of 
                      // the toolstrip into view. (space after the fact doesnt count).
                       if (cellMargin.Top >= spaceToFree) {
                          cellMargin.Top -= spaceToFree;
                          cellMargin.Bottom = 0; 
                          spaceToFree = 0;
 
                      } 
                      else {
                          spaceToFree -= lastCellOnRow.Margin.Top; 
                          cellMargin.Top = 0;
                          cellMargin.Bottom = 0;
                      }
                      lastCellOnRow.Margin = cellMargin; 

                      // start moving the toolstrips before this guy. 
                      spaceToFree -= MoveUp(Row.Cells.Count -1, spaceToFree); 

                      if (spaceToFree > 0) { 
                          spaceToFree -= lastCellOnRow.Shrink(spaceToFree);
                      }
                   }
                   return requiredSpace - Math.Max(0,spaceToFree); 
            }
 
 

            public override void MoveControl(ToolStrip movingControl, Point clientStartLocation, Point clientEndLocation) { 

                if (Row.Locked) {
                    return;
                } 
                if (DragBounds.Contains(clientEndLocation)) {
                   int index = Row.ControlsInternal.IndexOf(movingControl); 
                   int deltaY = clientEndLocation.Y - clientStartLocation.Y; 

                   if (deltaY < 0) { 
                       // moving to the left
                       MoveUp(index, deltaY * -1);
                   }
                   else { 
                       MoveDown(index, deltaY);
                   } 
               } 
               else {
                    base.MoveControl(movingControl, clientStartLocation, clientEndLocation); 
               }
            }

 

            private int MoveUp(int index, int spaceToFree) { 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp: " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                int freedSpace = 0;
 
                Row.SuspendLayout();
                try {
                    if (spaceToFree == 0 || index < 0) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp Early EXIT - 0 "); 
                        return 0;
                    } 
 

                    // remove all margins starting from the index. 
                    for (int i = index; i >= 0; i--) {
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) {
                            continue; 
                        }
                        int requiredSpace = spaceToFree - freedSpace; 
 
                        Padding cellMargin = cell.Margin;
 
                        if (cellMargin.Vertical >= requiredSpace) {
                            freedSpace += requiredSpace;

                            cellMargin.Top -= requiredSpace; 
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin; 
 
                        }
                        else { 
                            freedSpace += cell.Margin.Vertical;
                            cellMargin.Top = 0;
                            cellMargin.Bottom = 0;
                            cell.Margin = cellMargin; 
                        }
 
                        if (freedSpace >= spaceToFree) { 
                            // add the space we freed to the next guy.
                            if (index +1 < Row.Cells.Count) { 
                                cell = GetNextVisibleCell(index+1, /*forward*/true);
                                if (cell != null) {
                                    cellMargin = cell.Margin;
                                    cellMargin.Top += spaceToFree; 
                                    cell.Margin = cellMargin;
                                } 
                            } 

                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveUp Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                            return spaceToFree;
                        }
                    }
                } 
                finally {
                    Row.ResumeLayout(true); 
                } 

                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveLeft Recovered Partial (Shrink): " + freedSpace.ToString(CultureInfo.InvariantCulture)); 

                return freedSpace;
            }
 
            private int MoveDown(int index, int spaceToFree) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown: " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                int freedSpace = 0;
                Row.SuspendLayout(); 
                try {

                    if (spaceToFree == 0 || index < 0 || index >= Row.ControlsInternal.Count) {
                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Early EXIT - 0 "); 
                        return 0;
                    } 
 

                    ToolStripPanelCell cell; 
                    Padding cellMargin;

                    // remove all margins after this point in the index.
                    for (int i = index+1; i < Row.Cells.Count; i++) { 
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue; 
                        }
 
                        int requiredSpace = spaceToFree - freedSpace;

                        cellMargin = cell.Margin;
 
                        if (cellMargin.Vertical >= requiredSpace) {
                            freedSpace += requiredSpace; 
 
                            cellMargin.Top -= requiredSpace;
                            cellMargin.Bottom = 0; 
                            cell.Margin = cellMargin;

                        }
                        else { 
                            freedSpace += cell.Margin.Vertical;
                            cellMargin.Top = 0; 
                            cellMargin.Bottom = 0; 
                            cell.Margin = cellMargin;
                        } 

                        break;
                    }
 
                    // add in the space at the end of the row.
                    if (Row.Cells.Count > 0 && (spaceToFree > freedSpace)) { 
                        ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward*/false); 
                        if (lastCell != null) {
                            freedSpace += DisplayRectangle.Bottom - lastCell.Bounds.Bottom; 
                        }
                        else {
                            freedSpace += DisplayRectangle.Height;
                        } 
                    }
 
                    // set the margin of the control that's moving. 
                    if (spaceToFree <= freedSpace) {
                        // add the space we freed to the first guy. 
                        cell = (ToolStripPanelCell)Row.Cells[index];
                        cellMargin = cell.Margin;
                        cellMargin.Top += spaceToFree;
                        cell.Margin = cellMargin; 

                        Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered (Margin only): " + spaceToFree.ToString(CultureInfo.InvariantCulture)); 
                        return spaceToFree; 
                    }
 
                    // Now start shrinking.
                    for (int i = index+1; i < Row.Cells.Count; i++) {
                        cell = (ToolStripPanelCell)Row.Cells[i];
                        if (!cell.Visible && !cell.ControlInDesignMode) { 
                            continue;
                        } 
                        int requiredSpace = spaceToFree - freedSpace; 
                        freedSpace += cell.Shrink(requiredSpace);
 
                         if (spaceToFree >= freedSpace) {
                            Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered (Shrink): " + spaceToFree.ToString(CultureInfo.InvariantCulture));
                            Row.ResumeLayout(true);
                            return spaceToFree; 
                         }
 
                    } 

                    if (Row.Cells.Count == 1) { 
                        cell = GetNextVisibleCell(index,/*forward*/true);
                        if (cell != null) {
                            cellMargin = cell.Margin;
                            cellMargin.Top += freedSpace; 
                            cell.Margin = cellMargin;
                        } 
                    } 

                } 
                finally {
                    Row.ResumeLayout(true);
                }
 
                int recoveredSpace = spaceToFree - freedSpace;
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "MoveDown Recovered Partial (Shrink): " + recoveredSpace.ToString(CultureInfo.InvariantCulture)); 
 
                return recoveredSpace;
            } 

            protected internal override void OnBoundsChanged(Rectangle oldBounds, Rectangle newBounds) {

                base.OnBoundsChanged(oldBounds, newBounds); 

                // if our bounds have changed - we should shove the toolbars up so they're in view. 
                if (Row.Cells.Count > 0) { 

                    // take a look at the last guy.  if his right edge exceeds 
                    // the new bounds, then we should go ahead and push him into view.
                    ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count -1, /*forward=*/false);
                    int spaceToFree = (lastCell != null)?  lastCell.Bounds.Bottom - newBounds.Height : 0;
 
                    if (spaceToFree > 0){
                        // we should shrink the last guy and then move him. 
                        ToolStripPanelCell lastCellOnRow = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false); 

                        Padding cellMargin = lastCellOnRow.Margin; 

                        // only check margin.left as we are only concerned with getting bottom edge of
                        // the toolstrip into view. (space after the fact doesnt count).
                         if (cellMargin.Top >= spaceToFree) { 

                            cellMargin.Top -= spaceToFree; 
                            cellMargin.Bottom = 0; 
                            lastCellOnRow.Margin = cellMargin;
                            spaceToFree = 0; 

                        }
                        else {
                            spaceToFree -= lastCellOnRow.Margin.Top; 
                            cellMargin.Top = 0;
                            cellMargin.Bottom = 0; 
                            lastCellOnRow.Margin = cellMargin; 
                        }
                        spaceToFree -= lastCellOnRow.Shrink(spaceToFree); 
                        // start moving the toolstrips before this guy.
                        MoveUp(Row.Cells.Count -1, spaceToFree);
                     }
 
                }
 
            } 

 


            protected internal override void OnControlRemoved(Control c, int index) {
 
            }
 
            protected internal override void OnControlAdded(Control control, int index) { 

            } 


            public override void JoinRow(ToolStrip toolStripToDrag, Point locationToDrag) {
 
                Debug.WriteLineIf(ToolStripPanelMouseDebug.TraceVerbose, "Vertical JoinRow called " );
                int index; 
 
                if (!Row.ControlsInternal.Contains(toolStripToDrag)) {
                    Row.SuspendLayout(); 
                    try {
                        if (Row.ControlsInternal.Count > 0) {

 
                            // walk through the columns and determine which column you want to insert into.
                            for (index = 0; index < Row.Cells.Count; index++) { 
                                ToolStripPanelCell cell = Row.Cells[index] as ToolStripPanelCell; 
                                if (!cell.Visible && !cell.ControlInDesignMode) {
                                    continue; 
                                }
                                //  [:   ]  [: x  ]
                                if (cell.Bounds.Contains(locationToDrag)) {
                                    break; 
                                }
 
                                // take into account the following scenarios 
                                //  [:   ]  x [:   ]
                                // x [:  ]    [:   ] 
                                if (cell.Bounds.Y >= locationToDrag.Y) {
                                    break;
                                }
 
                            }
 
                            Control controlToPushAside = Row.ControlsInternal[index]; 
                            // Plop the new control in the midst of the row in question.
                            if (index < Row.ControlsInternal.Count) { 
                                Row.ControlsInternal.Insert(index, toolStripToDrag);
                            }
                            else {
                                Row.ControlsInternal.Add(toolStripToDrag); 
                            }
 
                            // since layout is suspended the control may not be set to its preferred size yet 
                            int controlToDragWidth = (toolStripToDrag.AutoSize) ? toolStripToDrag.PreferredSize.Height : toolStripToDrag.Height;
 
                            //
                            // now make it look like it belongs in the row.
                            //
                            // PUSH the controls after it to the right 

                            int requiredSpace = controlToDragWidth; 
 
                            if (index == 0) {
                                // make sure we account for the left side 
                                requiredSpace += locationToDrag.Y;
                            }
                            int freedSpace = 0;
 
                            if (index < Row.ControlsInternal.Count -1) {
 
                                ToolStripPanelCell nextCell = GetNextVisibleCell(index+1,  /*forward*/true); 
                                if (nextCell != null) {
                                    Padding nextCellMargin =  nextCell.Margin; 

                                    // if we've already got the empty space
                                    // (available to us via the margin) use that.
                                    if (nextCellMargin.Top > requiredSpace) { 
                                        nextCellMargin.Top -= requiredSpace;
                                        nextCell.Margin = nextCellMargin; 
                                        freedSpace = requiredSpace; 
                                    }
                                    else { 
                                        // otherwise we've got to
                                        // push all controls after this point to the right
                                        // this dumps the extra stuff into the margin of index+1
                                        freedSpace = MoveDown(index+1, requiredSpace - freedSpace); 

                                        // refetch the margin for "index+1" and remove the freed space 
                                        // from it - we want to actually put this to use on the control 
                                        // before this one - we're making room for the control at
                                        // position "index" 
                                        if (freedSpace > 0) {
                                            nextCellMargin =  nextCell.Margin;
                                            nextCellMargin.Top -= freedSpace;
                                            nextCell.Margin = nextCellMargin; 
                                        }
 
                                    } 
                                }
 

                            }
                            else {
                                 // we're adding to the end. 
                                ToolStripPanelCell nextCell = GetNextVisibleCell(Row.Cells.Count-2,  /*forward*/false);
                                ToolStripPanelCell lastCell = GetNextVisibleCell(Row.Cells.Count-1,  /*forward*/false); 
 
                                // count the stuff at the end of the row as freed space
                                if (nextCell != null && lastCell != null) { 
                                    Padding lastCellMargin =  lastCell.Margin;
                                    lastCellMargin.Top = Math.Max(0,locationToDrag.Y - nextCell.Bounds.Bottom);
                                    lastCell.Margin = lastCellMargin;
                                    freedSpace=requiredSpace; 
                                }
 
                            } 

                            // If we still need more space, then... 
                            // PUSH the controls before it to the left
                            if (freedSpace < requiredSpace && index > 0) {
                                freedSpace = MoveUp(index - 1, requiredSpace - freedSpace);
                            } 

 
                            if (index == 0) { 
                                // if the index is zero and there were controls in the row
                                // we need to take care of pushing over the new cell. 
                                if (freedSpace - controlToDragWidth > 0) {
                                    ToolStripPanelCell newCell = Row.Cells[index] as ToolStripPanelCell;
                                    Padding newCellMargin =  newCell.Margin;
                                    newCellMargin.Top = freedSpace - controlToDragWidth; 
                                    newCell.Margin = newCellMargin;
                                } 
                            } 

                        } 
                        else {

                            // we're adding to the beginning.
                            Row.ControlsInternal.Add(toolStripToDrag); 

#if DEBUG 
                            ISupportToolStripPanel ctg = toolStripToDrag as ISupportToolStripPanel; 
                            ToolStripPanelRow newPanelRow = ctg.ToolStripPanelRow;
                            Debug.Assert(newPanelRow == Row, "we should now be in the new panel row."); 
#endif
                            if (Row.Cells.Count >0) {
                                ToolStripPanelCell cell = GetNextVisibleCell(Row.Cells.Count-1, /*forward*/false);
                                if (cell != null) { 
                                    Padding cellMargin = cell.Margin;
                                    cellMargin.Top = Math.Max(0,locationToDrag.Y-Row.Margin.Top); 
                                    cell.Margin = cellMargin; 
                                }
                            } 
                        }
                    }
                    finally {
                        Row.ResumeLayout(true); 
                    }
                } 
            } 

            public override void LeaveRow(ToolStrip toolStripToDrag) { 
                // this code is here to properly add space to the next control when the
                // toolStripToDrag has been removed from the row.
                Row.SuspendLayout();
                int index = Row.ControlsInternal.IndexOf(toolStripToDrag); 
                if (index >= 0) {
                    if (index < Row.ControlsInternal.Count -1 /*not the last one in the row*/) { 
 
                        ToolStripPanelCell cell = (ToolStripPanelCell)Row.Cells[index];
                        if (cell.Visible) { 
                            int spaceOccupiedByCell = cell.Margin.Vertical + cell.Bounds.Height;

                            // add the space occupied by the cell to the next one.
                            ToolStripPanelCell nextCell = GetNextVisibleCell(index+1, /*forward*/true); 
                            if (nextCell != null) {
                                Padding nextCellMargin = nextCell.Margin; 
                                nextCellMargin.Top += spaceOccupiedByCell; 
                                nextCell.Margin = nextCellMargin;
                            } 
                        }
                    }
                    // remove the control from the row.
                    ((IList)Row.Cells).RemoveAt(index); 
                }
                Row.ResumeLayout(true); 
            } 
        }
 


        /// 
        /// ToolStripPanelRowControlCollection 
        ///
        /// this class represents the collection of controls on a particular row. 
        /// when you add and remove controls from this collection - you also add and remove 
        /// controls to and from the ToolStripPanel.Control's collection (which happens
        /// to be externally readonly.) 
        ///
        /// This class is used to represent the IArrangedElement.Children for the ToolStripPanelRow -
        /// which means that this collection represents the IArrangedElements to layout for
        /// a particular ToolStripPanelRow. 
        ///
        /// We need to keep copies of the controls in both the ToolStripPanelRowControlCollection and 
        /// the ToolStripPanel.Control collection  as the ToolStripPanel.Control collection 
        /// is responsible for parenting and unparenting the controls (ToolStripPanelRows do NOT derive from
        /// Control and thus are NOT hwnd backed). 
        /// 
        /// 
        internal class ToolStripPanelRowControlCollection : ArrangedElementCollection, IList, IEnumerable {
            private ToolStripPanelRow owner; 
            private ArrangedElementCollection cellCollection;
 
            ///  
            public ToolStripPanelRowControlCollection(ToolStripPanelRow owner) {
                this.owner = owner; 
            }


            ///  
            public ToolStripPanelRowControlCollection(ToolStripPanelRow owner, Control[] value) {
                this.owner = owner; 
                AddRange(value); 
            }
 
            /// 
            public new virtual Control this[int index] {
                get {
                    return GetControl(index); 
                }
            } 
 
            public ArrangedElementCollection Cells {
                get { 
                    if (cellCollection == null) {
                        cellCollection = new ArrangedElementCollection(InnerList);
                    }
                    return cellCollection; 
                }
            } 
 

            ///  
            public ToolStripPanel ToolStripPanel {
                get {
                    return owner.ToolStripPanel;
                } 
            }
 
            ///  
            /// 
            /// [To be supplied.] 
            /// 
            [EditorBrowsable(EditorBrowsableState.Never)]
            public int Add(Control value) {
                ISupportToolStripPanel control = value as ISupportToolStripPanel; 

                if (value == null) { 
                    throw new ArgumentNullException("value"); 
                }
                if (control == null) { 
                    throw new NotSupportedException(SR.GetString(SR.TypedControlCollectionShouldBeOfType, typeof(ToolStrip).Name));
                }

                int index = InnerList.Add(control.ToolStripPanelCell); 

                OnAdd(control, index); 
                return index; 
            }
 
            /// 
            /// 
            /// [To be supplied.]
            ///  
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
            [EditorBrowsable(EditorBrowsableState.Never)] 
            public void AddRange(Control[] value) { 
                if (value == null) {
                    throw new ArgumentNullException("value"); 
                }

                ToolStripPanel currentOwner = ToolStripPanel;
 
                if (currentOwner != null) {
                    currentOwner.SuspendLayout(); 
                } 

                try { 
                    for (int i = 0; i < value.Length; i++) {
                        this.Add(value[i]);
                    }
                } 
                finally {
                    if (currentOwner != null) { 
                        currentOwner.ResumeLayout(); 
                    }
                } 
            }

            /// 
            ///  
            /// [To be supplied.]
            ///  
            public bool Contains(Control value) { 
                for (int i = 0; i < Count; i++) {
                    if (GetControl(i) == value) { 
                        return true;
                    }
                }
                return false; 
            }
 
            ///  
            /// 
            /// [To be supplied.] 
            /// 
            public virtual void Clear() {
                if (owner != null) {
                    ToolStripPanel.SuspendLayout(); 
                }
 
                try { 
                    while (Count != 0) {
                        RemoveAt(Count - 1); 
                    }
                }
                finally {
                    if (owner != null) { 
                        ToolStripPanel.ResumeLayout();
                    } 
                } 
            }
 
            public override IEnumerator GetEnumerator() { return new ToolStripPanelCellToControlEnumerator(InnerList); }

            private Control GetControl(int index) {
                Control control = null; 
                ToolStripPanelCell cell = null;
 
                if (index < Count && index >= 0) { 
                    cell  = (ToolStripPanelCell)(InnerList[index]);
                    control = (cell != null) ? cell.Control : null; 
                }
                return control;

            } 
            private int IndexOfControl(Control c) {
                for (int i = 0; i < Count; i++) { 
                    ToolStripPanelCell cell  = (ToolStripPanelCell)(InnerList[i]); 
                    if (cell.Control == c) {
                        return i; 
                    }
                }
                return -1;
 
            }
 
 

 
            void IList.Clear() { Clear(); }

            bool IList.IsFixedSize { get { return InnerList.IsFixedSize; } }
 
            bool IList.Contains(object value) { return InnerList.Contains(value); }
 
            bool IList.IsReadOnly { get { return InnerList.IsReadOnly; } } 

            void IList.RemoveAt(int index) { RemoveAt(index); } 

            void IList.Remove(object value) { Remove(value as Control); }

            int IList.Add(object value) { return Add(value as Control); } 

            int IList.IndexOf(object value) { return IndexOf(value as Control); } 
 
            void IList.Insert(int index, object value) { Insert(index, value as Control); }
 
            /// 
            /// 
            /// [To be supplied.]
            ///  
            public int IndexOf(Control value) {
                for (int i = 0; i < Count; i++) { 
                    if (GetControl(i) == value) { 
                        return i;
                    } 
                }
                return -1;
            }
 
            /// 
            ///  
            /// [To be supplied.] 
            /// 
            [EditorBrowsable(EditorBrowsableState.Never)] 
            public void Insert(int index, Control value) {
                if (value == null) {
                    throw new ArgumentNullException("value");
                } 
                ISupportToolStripPanel control = value as ISupportToolStripPanel;
                if (control == null) { 
                    throw new NotSupportedException(SR.GetString(SR.TypedControlCollectionShouldBeOfType, typeof(ToolStrip).Name)); 
                }
 
                InnerList.Insert(index, control.ToolStripPanelCell);
                OnAdd(control, index);
            }
 
            /// 
            ///  Do proper cleanup of ownership, etc. 
            ///  
            private void OnAfterRemove(Control control, int index) {
                if (owner != null) { 
                    // unfortunately we dont know the index of the control in the ToolStripPanel's
                    // control collection, as all rows share this collection.
                    // To unparent this control we need to use Remove instead  of RemoveAt.
                    using (LayoutTransaction t = new LayoutTransaction(ToolStripPanel, control, PropertyNames.Parent)) { 
                        owner.ToolStripPanel.Controls.Remove(control);
                        owner.OnControlRemoved(control, index); 
                    } 
                }
            } 

            private void OnAdd(ISupportToolStripPanel controlToBeDragged, int index) {
                if (owner != null) {
                    LayoutTransaction layoutTransaction = null; 
                    if (ToolStripPanel != null && ToolStripPanel.ParentInternal != null) {
                        layoutTransaction = new LayoutTransaction(ToolStripPanel, ToolStripPanel.ParentInternal, PropertyNames.Parent); 
 
                    }
                    try { 

                        if (controlToBeDragged != null) {

                            controlToBeDragged.ToolStripPanelRow = owner; 

                            Control control = controlToBeDragged as Control; 
 
                            if (control != null) {
                                control.ParentInternal = owner.ToolStripPanel; 
                                owner.OnControlAdded(control, index);
                            }
                        }
 
                    }
                    finally { 
                        if (layoutTransaction != null) { 
                            layoutTransaction.Dispose();
                        } 
                    }

                }
            } 

            ///  
            ///  
            /// [To be supplied.]
            ///  

            [EditorBrowsable(EditorBrowsableState.Never)]
            public void Remove(Control value) {
                int index = IndexOfControl(value); 
                RemoveAt(index);
            } 
 
            /// 
            ///  
            /// [To be supplied.]
            /// 
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void RemoveAt(int index) { 
                if (index >= 0 && index < Count) {
                    Control control = GetControl(index); 
                    ToolStripPanelCell cell = InnerList[index] as ToolStripPanelCell; 
                    InnerList.RemoveAt(index);
                    OnAfterRemove(control, index); 
                }
            }

            ///  
            /// 
            /// [To be supplied.] 
            ///  
            [EditorBrowsable(EditorBrowsableState.Never)]
            public void CopyTo(Control[] array, int index) { 
                if (array == null) {
                    throw new ArgumentNullException("array");
                }
 
                if (index < 0) {
                    throw new ArgumentOutOfRangeException("index"); 
                } 

                if (index >= array.Length || InnerList.Count > array.Length - index) { 
                    throw new ArgumentException(SR.GetString(SR.ToolStripPanelRowControlCollectionIncorrectIndexLength));
                }

                for (int i = 0; i < InnerList.Count; i++) { 
                    array[index++] = GetControl(i);
                } 
            } 

            /// We want to pretend like we're only holding controls... so everywhere we've returned controls. 
            /// but the problem is if you do a foreach, you'll get the cells not the controls.  So we've got
            /// to sort of write a wrapper class around the ArrayList enumerator.
            private class ToolStripPanelCellToControlEnumerator : IEnumerator, ICloneable {
                private IEnumerator arrayListEnumerator; 

                internal ToolStripPanelCellToControlEnumerator(ArrayList list) { 
                    arrayListEnumerator = ((IEnumerable)list).GetEnumerator(); 
                }
 
                public virtual Object Current {
                    get {
                        ToolStripPanelCell cell = arrayListEnumerator.Current as ToolStripPanelCell;
                        Debug.Assert(cell != null, "Expected ToolStripPanel cells only!!!" + arrayListEnumerator.Current.GetType().ToString()); 
                        return (cell == null) ? null : cell.Control;
                    } 
                } 

 
                public Object Clone() {
                    return MemberwiseClone();
                }
 
                public virtual bool MoveNext() {
                    return arrayListEnumerator.MoveNext(); 
                } 

                public virtual void Reset() { 
                    arrayListEnumerator.Reset();
                }
            }
        } 
    }
} 
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK