SplitContainer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / WinForms / Managed / System / WinForms / SplitContainer.cs / 1 / SplitContainer.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
namespace System.Windows.Forms {
 
    using Microsoft.Win32;
    using System;
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Diagnostics.CodeAnalysis;
    using System.Drawing; 
    using System.Runtime.InteropServices; 
    using System.Runtime.Remoting;
    using System.Security; 
    using System.Security.Permissions;
    using System.Windows.Forms;
    using System.Collections;
    using System.Drawing.Drawing2D; 
    using System.Globalization;
 
    ///  
    /// 
    ///    A SplitContainer is a ContainerControl with 2 panels separated with a splitter 
    ///    in the middle. This is a composite control. The user can drag and drop this control from Toolbox.
    ///    Controls can be added to the right panel and the left panel. The Orientation can be either Horizontal or Vertical.
    ///    The Controls inside the Panels would be redrawn with the new Orientation.
    ///    With this control the user need be aware of docking, z-order of the controls. The controls get parented when thry are 
    ///    dropped on the SpitContainer.
    ///  
    [ 
    ComVisible(true),
    ClassInterface(ClassInterfaceType.AutoDispatch), 
    DefaultEvent("SplitterMoved"),
    Docking(DockingBehavior.AutoDock),
    Designer("System.Windows.Forms.Design.SplitContainerDesigner, " + AssemblyRef.SystemDesign),
    SRDescription(SR.DescriptionSplitContainer) 
    ]
    public class SplitContainer : ContainerControl 
    { 

        // 
        // CONTANTS USED DURING DRAWING SPLITTER MOOVEMENTS
        //
        private const int DRAW_START = 1;
        private const int DRAW_MOVE = 2; 
        private const int DRAW_END = 3;
        private const int rightBorder = 5; 
        private const int leftBorder = 2; 

        private int BORDERSIZE = 0; 


        //
        // SplitContainer private Cached copies of public properties... 
        //
        private Orientation orientation = Orientation.Vertical; 
        private SplitterPanel panel1 = null; 
        private SplitterPanel panel2 = null;
        private BorderStyle borderStyle = System.Windows.Forms.BorderStyle.None; 
        private FixedPanel fixedPanel = FixedPanel.None;

        private int panel1MinSize = 25; //Panel1 Minimum Size
        private int panel2MinSize = 25; //Panel2 Minimum Size 
        private bool tabStop = true;
        // 
        //Fixed panel width or height; 
        //
        private int panelSize; 

        //
        //SPLITTER PROPERTIES
        // 
        private Rectangle splitterRect;
        private int splitterInc = 1; 
        private bool splitterFixed; 
        private int splitterDistance = 50; //default splitter distance;
        private int splitterWidth = 4; 
        private int splitDistance = 50;

        //
        //Properties used using DRAWING a MOVING SPLITTER 
        //
        private int lastDrawSplit =1; 
        private int initialSplitterDistance; 
        private Rectangle initialSplitterRectangle;
        private Point anchor = Point.Empty; 
        private bool splitBegin = false;
        private bool splitMove = false;
        private bool splitBreak = false;
 
        //
        // Split Cursor 
        // 
        Cursor overrideCursor = null;
 
        //
        //Needed For Tabbing
        //
        Control nextActiveControl = null; 
        private bool callBaseVersion;
        private bool splitterFocused; 
 
        //
        //Required to keep track of Splitter movements.... 
        //
        private bool splitterClick;
        private bool splitterDrag;
 
        //
        // FixedPanel.None require us 
        // to keep the Width/Height Ratio Depending on SplitContainer.Orientation 
        //
 
        double ratioWidth = 0.0f;
        double ratioHeight = 0.0f;
        bool resizeCalled = false;
        bool splitContainerScaling = false; 
        bool setSplitterDistance = false;
 
        // 
        //Events
        // 
        private static readonly object EVENT_MOVING = new object();
        private static readonly object EVENT_MOVED = new object();

        // private IMessageFilter implementation 
        SplitContainerMessageFilter splitContainerMessageFilter = null;
 
 		//This would avoid re-entrant code into SelectNextControl. 
		private bool selectNextControl = false;
 
        //
        // Constructor
        //
        ///  
        public SplitContainer()
        { 
            // either the left or top panel - LTR 
            // either the right or top panel - RTL
            panel1 = new SplitterPanel(this); 
            // either the right or bottom panel - LTR
            // either the left or bottom panel - RTL
            panel2 = new SplitterPanel(this);
            splitterRect = new Rectangle(); 

            SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 

            ((WindowsFormsUtils.TypedControlCollection)this.Controls).AddInternal(panel1); 
            ((WindowsFormsUtils.TypedControlCollection)this.Controls).AddInternal(panel2);
            UpdateSplitter();

        } 

        ///////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                                         // 
        //PROPERTIES START IN ALPHABETICAL ORDER                                                   //
        //                                                                                         // 
        /////////////////////////////////////////////////////////////////////////////////////////////


 

        ///  
        ///  
        ///     This property is overridden to allow the AutoScroll to be set on all the panels when
        ///     The autoScroll on SplitContainer is shown. 
        ///     Here we dont set the base value ... but set autoscroll for panels.
        /// 
        [
        SRCategory(SR.CatLayout), 
        Localizable(true),
        DefaultValue(false), 
        SRDescription(SR.FormAutoScrollDescr), 
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never)
        ] 
        public override bool AutoScroll {
            get {
                //Always return false ... as Splitcontainer doesnt support AutoScroll
                return false; 
            }
 
            set { 
                base.AutoScroll = value;
            } 
        }

        [
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Never),
        DefaultValue(typeof(Point), "0, 0") 
        ] 
        public override Point AutoScrollOffset {
            get { 
               return base.AutoScrollOffset;
            }
            set {
                base.AutoScrollOffset = value; 
            }
        } 
 
        /// 
        ///  
        ///    Override AutoScrollMinSize to make it hidden from the user in the designer
        /// 
        [
        EditorBrowsable(EditorBrowsableState.Never), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        Browsable(false) 
        ] 
        public new Size AutoScrollMinSize {
            get { 
                return base.AutoScrollMinSize;
            }
            set {
                base.AutoScrollMinSize = value; 
            }
        } 
 

        ///  
        /// 
        ///    Override AutoScrollMargin to make it hidden from the user in the designer
        /// 
        [ 
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        Browsable(false) 
        ]
        public new Size AutoScrollMargin { 
            get {
                return base.AutoScrollMargin;
            }
            set { 
                base.AutoScrollMargin = value;
            } 
        } 

 
        [
        SRCategory(SR.CatLayout),
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.FormAutoScrollPositionDescr)
        ] 
        public new Point AutoScrollPosition { 
            get {
                return base.AutoScrollPosition; 
            }

            set {
                base.AutoScrollPosition = value; 
            }
        } 
 
        /// 
        ///     Hide AutoSize, as it can mean more than one thing and might confuse users 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override bool AutoSize 
        {
            get 
            { 
                return base.AutoSize;
            } 
            set
            {
                base.AutoSize = value;
            } 
        }
 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler AutoSizeChanged { 
            add {
                base.AutoSizeChanged += value;
            }
            remove { 
                base.AutoSizeChanged -= value;
            } 
        } 

 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        public override Image BackgroundImage { 
            get { 
                return base.BackgroundImage;
            } 
            set {
                base.BackgroundImage = value;
            }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override ImageLayout BackgroundImageLayout {
            get {
                return base.BackgroundImageLayout; 
            }
            set { 
                base.BackgroundImageLayout = value; 
            }
        } 


        /// 
        ///  
        /// 
        ///     
        ///       The binding manager for the container control. 
        ///    
        ///  
        [
        Browsable(false),
        SRDescription(SR.ContainerControlBindingContextDescr),
        SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly") 
        ]
        public override BindingContext BindingContext { 
            get { 
                return BindingContextInternal;
            } 
            set {
                BindingContextInternal = value;
            }
        } 

        ///  
        ///  
        ///     Indicates what type of border the Splitter control has.  This value
        ///     comes from the System.Windows.Forms.BorderStyle enumeration. 
        /// 
        [
        DefaultValue(BorderStyle.None),
        SRCategory(SR.CatAppearance), 
        System.Runtime.InteropServices.DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE),
        SRDescription(SR.SplitterBorderStyleDescr) 
        ] 
        public BorderStyle BorderStyle {
            get { 
                return borderStyle;
            }

            set { 
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)){ 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle)); 
                }
 
                if (borderStyle != value) {
                    borderStyle = value;
                    Invalidate();
                    SetInnerMostBorder(this); 
                    if (this.ParentInternal != null) {
                        if (this.ParentInternal is SplitterPanel) { 
                            SplitContainer sc = (SplitContainer)((SplitterPanel)this.ParentInternal).Owner; 
                            sc.SetInnerMostBorder(sc);
                        } 
                    }
                }

                switch (BorderStyle) 
                {
                    case BorderStyle.None: 
                        BORDERSIZE = 0; 
                        break;
                    case BorderStyle.FixedSingle: 
                        BORDERSIZE = 1;
                        break;
                    case BorderStyle.Fixed3D:
                        BORDERSIZE = 4; 
                        break;
                } 
            } 
        }
 
        /// 
        /// 
        ///     Controls Collection...
        ///     This is overriden so that the Controls.Add ( ) is not Code Gened... 
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public new Control.ControlCollection Controls {
            get { 
                return base.Controls;
            }
        }
 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event ControlEventHandler ControlAdded { 
            add {
                base.ControlAdded += value; 
            }
            remove {
                base.ControlAdded -= value;
            } 
        }
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event ControlEventHandler ControlRemoved {
             add { 
                 base.ControlRemoved += value;
             }
             remove {
                 base.ControlRemoved -= value; 
             }
        } 
        ///  
        /// 
        ///     The dock property. The dock property controls to which edge 
        ///     of the container this control is docked to. For example, when docked to
        ///     the top of the container, the control will be displayed flush at the
        ///     top of the container, extending the length of the container.
        ///  
        public new DockStyle Dock {
            get { 
                return base.Dock; 
            }
            set { 
                base.Dock = value;
                if (this.ParentInternal != null) {
                    if (this.ParentInternal is SplitterPanel) {
                        SplitContainer sc = (SplitContainer)((SplitterPanel)this.ParentInternal).Owner; 
                        sc.SetInnerMostBorder(sc);
                    } 
                } 
                ResizeSplitContainer();
            } 
        }

        /// 
        ///  
        ///     Deriving classes can override this to configure a default size for their control.
        ///     This is more efficient than setting the size in the control's constructor. 
        ///  
        protected override Size DefaultSize {
            get { 
                return new Size(150, 100);
            }
        }
 
        /// 
        ///  
        ///     Indicates what type of border the Splitter control has.  This value 
        ///     comes from the System.Windows.Forms.BorderStyle enumeration.
        ///  
        [
        DefaultValue(FixedPanel.None),
        SRCategory(SR.CatLayout),
        SRDescription(SR.SplitContainerFixedPanelDescr) 
        ]
        public FixedPanel FixedPanel { 
            get { 
                return fixedPanel;
            } 

            set {
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)FixedPanel.None, (int)FixedPanel.Panel2)){ 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(FixedPanel));
                } 
 
                if (fixedPanel != value) {
                    fixedPanel = value; 
                    // UpdatePanelSize !!
                    switch (fixedPanel) {
                        case FixedPanel.Panel2:
                            if (Orientation == Orientation.Vertical) { 
                                panelSize  = Width - SplitterDistanceInternal - SplitterWidthInternal;
                            } 
                            else { 
                                panelSize  = Height - SplitterDistanceInternal - SplitterWidthInternal;
                            } 
                            break;
                        default:
                            panelSize  =   SplitterDistanceInternal;
                            break; 
                    }
                } 
            } 
        }
 
        /// 
        /// 
        /// This property determines whether the the splitter can move.
        ///  
        [
        SRCategory(SR.CatLayout), 
        DefaultValue(false), 
        Localizable(true),
        SRDescription(SR.SplitContainerIsSplitterFixedDescr) 
        ]

        public bool IsSplitterFixed {
            get { 
                return splitterFixed;
            } 
            set { 
                splitterFixed = value;
            } 
        }

        //Private property used to check whether the splitter can be moved by the user.
        private bool IsSplitterMovable { 
            get {
                 if (Orientation == Orientation.Vertical) { 
                     return (Width >= Panel1MinSize + SplitterWidthInternal + Panel2MinSize); 
                 }
                 else { 
                     return (Height >= Panel1MinSize + SplitterWidthInternal + Panel2MinSize);
                 }

            } 
        }
 
        // VsWhidbey 434959 : Refer to IsContainerControl property on Control for more details. 
        internal override bool IsContainerControl
        { 
            get
            {
                return true;
            } 
        }
 
        ///  
        /// 
        /// This Property sets or gets if the splitter is vertical or horizontal. 
        /// 
        [
        SRCategory(SR.CatBehavior),
        DefaultValue(Orientation.Vertical), 
        Localizable(true),
        SRDescription(SR.SplitContainerOrientationDescr) 
        ] 
        public Orientation Orientation {
            get { return  orientation; } 
            set {
                //valid values are 0x0 to 0x1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)Orientation.Horizontal, (int)Orientation.Vertical)){
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(Orientation)); 
                }
                if (orientation != value) { 
                    orientation = value; 
					//update the splitterDistance to validate it w.r.t the new Orientation.
					splitDistance = 0; 
 					SplitterDistance = SplitterDistanceInternal;
                    UpdateSplitter();
                }
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        private Cursor OverrideCursor {
            get {
                return overrideCursor; 
            }
            set { 
                if (overrideCursor != value) { 
                    overrideCursor = value;
 
                    if (IsHandleCreated) {
                        // We want to instantly change the cursor if the mouse is within our bounds.
                        NativeMethods.POINT p = new NativeMethods.POINT();
                        NativeMethods.RECT r = new NativeMethods.RECT(); 
                        UnsafeNativeMethods.GetCursorPos(p);
                        UnsafeNativeMethods.GetWindowRect(new HandleRef(this, Handle), ref r); 
                        if ((r.left <= p.x && p.x < r.right && r.top <= p.y && p.y < r.bottom) || UnsafeNativeMethods.GetCapture() == Handle) 
                            SendMessage(NativeMethods.WM_SETCURSOR, Handle, NativeMethods.HTCLIENT);
                    } 
                }
            }
        }
 
        ///
        /// Indicates if either panel is collapsed 
        /// 
        private bool CollapsedMode {
            get { 
                return Panel1Collapsed || Panel2Collapsed;
            }
        }
 
        /// 
        ///  
        /// The Left or Top panel in the SplitContainer. 
        /// 
        [ 
        SRCategory(SR.CatAppearance),
        SRDescription(SR.SplitContainerPanel1Descr),
        Localizable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content) 
        ]
        public SplitterPanel Panel1 { 
            get { 
                return this.panel1;
            } 
        }

        ///
        ///     Collapses or restores the given panel 
        ///
        private void CollapsePanel(SplitterPanel p, bool collapsing) { 
            p.Collapsed = collapsing; 
            if (collapsing) {
                p.Visible = false; 

            }
            else {
                // restore panel 
                p.Visible = true;
            } 
            UpdateSplitter(); 
        }
 
        /// 
        /// 
        ///    
        ///    [To be supplied.] 
        ///    
        ///  
        [ 
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new Padding Padding {
            get { return base.Padding; } 
            set { base.Padding = value;}
        } 
 
        [
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        public new event EventHandler PaddingChanged {
            add { base.PaddingChanged += value; } 
            remove { base.PaddingChanged -= value; }
        } 
 
        /// 
        ///  
        /// Collapses or restores panel1
        /// 
        [
        SRCategory(SR.CatLayout), 
        DefaultValue(false),
        SRDescription(SR.SplitContainerPanel1CollapsedDescr) 
        ] 
        public bool Panel1Collapsed {
            get { 
                return panel1.Collapsed;
            }
            set {
                if (value != panel1.Collapsed) { 
                    if (value && panel2.Collapsed) {
                        CollapsePanel(panel2, false); 
                    } 
                    CollapsePanel(panel1, value);
                } 
            }
        }

 
        /// 
        ///  
        /// Collapses or restores panel2 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        DefaultValue(false),
        SRDescription(SR.SplitContainerPanel2CollapsedDescr)
        ] 
        public bool Panel2Collapsed {
            get { 
                return panel2.Collapsed; 
            }
            set { 
                if (value != panel2.Collapsed) {
                    if (value && panel1.Collapsed) {
                        CollapsePanel(panel1, false);
                    } 
                    CollapsePanel(panel2, value);
                } 
            } 
        }
 
        /// 
        /// 
        /// This property determines the minimum distance of pixels of the splitter from the left or the top edge of Panel1.
        ///  
        [
        SRCategory(SR.CatLayout), 
        DefaultValue(25), 
        Localizable(true),
        SRDescription(SR.SplitContainerPanel1MinSizeDescr), 
        RefreshProperties(RefreshProperties.All)
        ]
        public int Panel1MinSize {
            get { 
                return panel1MinSize;
            } 
            set { 
                if (value != Panel1MinSize)
                { 
                    if (value < 0)
                    {
                        throw new ArgumentOutOfRangeException("Panel1MinSize", SR.GetString(SR.InvalidLowBoundArgument, "Panel1MinSize", (value).ToString(CultureInfo.CurrentCulture), "0"));
                    } 

                    if (Orientation == Orientation.Vertical) { 
                       if (DesignMode && Width != DefaultSize.Width && value + Panel2MinSize + SplitterWidth > Width) 
                       {
                            throw new ArgumentOutOfRangeException("Panel1MinSize", SR.GetString(SR.InvalidArgument, "Panel1MinSize", (value).ToString(CultureInfo.CurrentCulture))); 
                       }

                    }
                    else if (Orientation == Orientation.Horizontal) { 
                        if (DesignMode && Height != DefaultSize.Height && value + Panel2MinSize + SplitterWidth > Height)
                        { 
                            throw new ArgumentOutOfRangeException("Panel1MinSize", SR.GetString(SR.InvalidArgument, "Panel1MinSize", (value).ToString(CultureInfo.CurrentCulture))); 
                        }
                    } 
                    panel1MinSize = value;
                    if (value > SplitterDistanceInternal) {
                        SplitterDistanceInternal = value;  //Set the Splitter Distance to the end of Panel1
                    } 
                }
            } 
        } 

        ///  
        /// 
        /// This is the Right or Bottom panel in the SplitContainer.
        /// 
        [ 
        SRCategory(SR.CatAppearance),
        SRDescription(SR.SplitContainerPanel2Descr), 
        Localizable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
        ] 
        public SplitterPanel Panel2 {
            get {
                return this.panel2;
            } 
        }
 
        ///  
        /// 
        /// This property determines the minimum distance of pixels of the splitter from the right or the bottom edge of Panel2 
        /// 
        [
        SRCategory(SR.CatLayout),
        DefaultValue(25), 
        Localizable(true),
        SRDescription(SR.SplitContainerPanel2MinSizeDescr), 
        RefreshProperties(RefreshProperties.All) 
        ]
        public int Panel2MinSize { 
            get {
                return panel2MinSize;
            }
            set { 
                if (value != Panel2MinSize)
                { 
                    if (value < 0) 
                    {
                        throw new ArgumentOutOfRangeException("Panel2MinSize", SR.GetString(SR.InvalidLowBoundArgument, "Panel2MinSize", (value).ToString(CultureInfo.CurrentCulture), "0")); 
                    }
                    if (Orientation == Orientation.Vertical) {
                        if (DesignMode && Width != DefaultSize.Width && value + Panel1MinSize + SplitterWidth > Width)
                        { 
                            throw new ArgumentOutOfRangeException("Panel2MinSize", SR.GetString(SR.InvalidArgument, "Panel2MinSize", (value).ToString(CultureInfo.CurrentCulture)));
                        } 
 
                    }
                    else if (Orientation == Orientation.Horizontal) { 
                        if (DesignMode && Height != DefaultSize.Height && value + Panel1MinSize + SplitterWidth > Height)
                        {
                            throw new ArgumentOutOfRangeException("Panel2MinSize", SR.GetString(SR.InvalidArgument, "Panel2MinSize", (value).ToString(CultureInfo.CurrentCulture)));
                        } 
                    }
                    panel2MinSize = value; 
                    if (value > Panel2.Width) { 
                        SplitterDistanceInternal = Panel2.Width + SplitterWidthInternal ;  //Set the Splitter Distance to the start of Panel2
                    } 
                }
            }
        }
 
        /// 
        ///  
        /// This property determines pixel distance of the splitter from the left or top edge. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        Localizable(true),
        SettingsBindable(true),
        SRDescription(SR.SplitContainerSplitterDistanceDescr), 
        DefaultValue(50)
        ] 
        public int SplitterDistance 
        {
            get 
            {
                return splitDistance;
            }
            set 
            {
                if (value != SplitterDistance) 
                { 
                    if (value < 0) {
                        throw new ArgumentOutOfRangeException("SplitterDistance", SR.GetString(SR.InvalidLowBoundArgument, "SplitterDistance", (value).ToString(CultureInfo.CurrentCulture), "0")); 
                    }


                    try 
                    {
                        setSplitterDistance = true; 
 
                        if (Orientation == Orientation.Vertical) {
 
                            if (value  < Panel1MinSize)
                            {
                                value = Panel1MinSize;
                            } 
                            if (value + SplitterWidthInternal > this.Width - Panel2MinSize)
                            { 
                                value = this.Width - Panel2MinSize - SplitterWidthInternal; 
                            }
                            if (value < 0 ) { 
                                throw new InvalidOperationException(SR.GetString(SR.SplitterDistanceNotAllowed));
                            }
                            splitDistance = value;
                            splitterDistance = value; 
                            panel1.WidthInternal = SplitterDistance;
 
                        } 
                        else {
 
                            if (value < Panel1MinSize)
                            {
                                value = Panel1MinSize;
                            } 

                            if (value + SplitterWidthInternal > this.Height - Panel2MinSize) 
                            { 
                                value = this.Height - Panel2MinSize - SplitterWidthInternal;
                            } 
                            if (value < 0 ) {
                                throw new InvalidOperationException(SR.GetString(SR.SplitterDistanceNotAllowed));
                            }
                            splitDistance = value; 
                            splitterDistance = value;
                            panel1.HeightInternal = SplitterDistance; 
                        } 

                        switch (fixedPanel) { 
                            case FixedPanel.Panel1:
                                panelSize  =   SplitterDistance;
                                break;
                            case FixedPanel.Panel2: 
                                if (Orientation == Orientation.Vertical) {
                                    panelSize  = Width - SplitterDistance - SplitterWidthInternal; 
                                } 
                                else {
                                    panelSize  = Height - SplitterDistance - SplitterWidthInternal; 
                                }
                                break;
                        }
                        UpdateSplitter(); 
                    }
                    finally 
                    { 
                        setSplitterDistance = false;
                    } 
                    OnSplitterMoved(new SplitterEventArgs(SplitterRectangle.X + SplitterRectangle.Width/2, SplitterRectangle.Y + SplitterRectangle.Height/2, SplitterRectangle.X, SplitterRectangle.Y));
                }
            }
        } 

        private int SplitterDistanceInternal { 
 
            get {
                return splitterDistance; 
            }
            set {
                SplitterDistance = value;
            } 
        }
 
        ///  
        /// 
        /// This determines the number of pixels the splitter moves in increments.This is defaulted to 1. 
        /// 
        [
        SRCategory(SR.CatLayout),
        DefaultValue(1), 
        Localizable(true),
        SRDescription(SR.SplitContainerSplitterIncrementDescr) 
        ] 
        public int SplitterIncrement {
            get { 
                return splitterInc;
            }
            set {
 
                if (value < 1 ) {
                    throw new ArgumentOutOfRangeException("SplitterIncrement", SR.GetString(SR.InvalidLowBoundArgumentEx, "SplitterIncrement", (value).ToString(CultureInfo.CurrentCulture), "1")); 
                } 

                splitterInc = value; 
            }
        }

 
        /// 
        ///  
        /// This property determines the rectangle bounds of the splitter. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        SRDescription(SR.SplitContainerSplitterRectangleDescr),
        Browsable(false)
        ] 
        public Rectangle SplitterRectangle {
            get { 
                Rectangle r = splitterRect; 
                r.X = splitterRect.X - Left;
                r.Y = splitterRect.Y - Top; 
                return r;
            }
        }
 
        /// 
        ///  
        /// This property determines the thickness of the splitter. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        SRDescription(SR.SplitContainerSplitterWidthDescr),
        Localizable(true),
        DefaultValue(4) 
        ]
        public int SplitterWidth { 
            get { 
                return splitterWidth;
            } 
            set {
                if (value != SplitterWidth)
                {
                    if (value < 1 ) { 
                        throw new ArgumentOutOfRangeException("SplitterWidth", SR.GetString(SR.InvalidLowBoundArgumentEx, "SplitterWidth", (value).ToString(CultureInfo.CurrentCulture), "1"));
                    } 
                    if (Orientation == Orientation.Vertical) { 
                       if (DesignMode && value + Panel1MinSize + Panel2MinSize > Width)
                       { 
                            throw new ArgumentOutOfRangeException("SplitterWidth", SR.GetString(SR.InvalidArgument, "SplitterWidth", (value).ToString(CultureInfo.CurrentCulture)));
                       }

                    } 
                    else if (Orientation == Orientation.Horizontal) {
                        if (DesignMode && value + Panel1MinSize + Panel2MinSize > Height) 
                        { 
                            throw new ArgumentOutOfRangeException("SplitterWidth", SR.GetString(SR.InvalidArgument, "SplitterWidth", (value).ToString(CultureInfo.CurrentCulture)));
                        } 
                    }
                    splitterWidth = value;
                    UpdateSplitter();
                } 
            }
        } 
 
        /// 
        ///    We need to have a internal Property for the SplitterWidth which returns zero if we are in collapased mode. 
        ///    This property is used to Layout SplitContainer.
        /// 
        private int SplitterWidthInternal {
            get { 
                // if CollapsedMode then splitterwidth == 0;
                return (CollapsedMode) ? 0 : splitterWidth; 
            } 
        }
 
        /// 
        /// 
        ///    Indicates whether the user can give the focus to this control using the TAB
        ///       key. This property is read-only. 
        /// 
        [ 
        SRCategory(SR.CatBehavior), 
        DefaultValue(true),
        DispId(NativeMethods.ActiveX.DISPID_TABSTOP), 
        SRDescription(SR.ControlTabStopDescr)
        ]
        public new bool TabStop {
            get { 
                return tabStop;
            } 
            set { 
                if (TabStop != value) {
                    tabStop = value; 
                    OnTabStopChanged(EventArgs.Empty);
                }
            }
        } 

        ///  
        ///  
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Bindable(false)] 
        public override string Text {
            get {
                return base.Text;
            } 
            set {
                base.Text = value; 
            } 
        }
 
        /////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                            //
        //END PROPERTIES                                                              //
        //                                                                            // 
        /////////////////////////////////////////////////////////////////////////////////////////////
 
 
        /////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                            // 
        //Start EVENT HANDLERS                                                        //
        //                                                                            //
        /////////////////////////////////////////////////////////////////////////////////////////////
 
        /// 
        ///  
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)] 
        new public event EventHandler BackgroundImageChanged {
            add { 
                base.BackgroundImageChanged += value;
            }
            remove {
                base.BackgroundImageChanged -= value; 
            }
        } 
 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackgroundImageLayoutChanged {
            add {
                base.BackgroundImageLayoutChanged += value; 
            }
            remove { 
                base.BackgroundImageLayoutChanged -= value; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [SRCategory(SR.CatBehavior), SRDescription(SR.SplitterSplitterMovingDescr)] 
        public event SplitterCancelEventHandler SplitterMoving { 
            add {
                Events.AddHandler(EVENT_MOVING, value); 
            }
            remove {
                Events.RemoveHandler(EVENT_MOVING, value);
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [SRCategory(SR.CatBehavior), SRDescription(SR.SplitterSplitterMovedDescr)]
        public event SplitterEventHandler SplitterMoved {
            add { 
                Events.AddHandler(EVENT_MOVED, value);
            } 
            remove { 
                Events.RemoveHandler(EVENT_MOVED, value);
            } 
        }

        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler TextChanged { 
            add { 
                base.TextChanged += value;
            } 
            remove {
                base.TextChanged -= value;
            }
        } 

        ///////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                            // 
        //End EVENT HANDLERS                                                          //
        //                                                                            // 
        /////////////////////////////////////////////////////////////////////////////////////////////


 
        /////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                            // 
        //start EVENT Delegates                                                       // 
        //                                                                            //
        ///////////////////////////////////////////////////////////////////////////////////////////// 

        /// 
        /// 
        ///     Overides the Control.OnGotFocus to Invalidate... 
        /// 
        protected override void OnGotFocus(EventArgs e) { 
            base.OnGotFocus(e); 
            Invalidate();
 
        }

        /// 
        ///  
        ///     Overrides the Control.OnKeydown for implementing splitter movements.
        ///  
        protected override void OnKeyDown(KeyEventArgs e) { 
            Debug.Assert(Enabled, "SplitContainer.OnKeyDown should not be called if the button is disabled");
            base.OnKeyDown(e); 
            //If the Panel1MinSize + Panel2MinSize < SplitContainer.Size then carry on the splitter move...
            if (IsSplitterMovable && !IsSplitterFixed) {
                if (e.KeyData == Keys.Escape && splitBegin) {
                    splitBegin = false; 
                    splitBreak = true;
                    return; 
                } 
                //valid Keys that move the splitter...
                if (e.KeyData == Keys.Right || e.KeyData == Keys.Down || 
                    e.KeyData == Keys.Left || e.KeyData == Keys.Up
                    && splitterFocused) {
                    if (splitBegin) {
                        splitMove = true; 
                    }
 
                    //left OR up 
                    if (e.KeyData == Keys.Left || e.KeyData == Keys.Up && splitterFocused) {
                        splitterDistance -= SplitterIncrement; 
                        splitterDistance = (splitterDistance < Panel1MinSize) ? splitterDistance + SplitterIncrement : Math.Max(splitterDistance, BORDERSIZE);
                    }
                    //right OR down
                    if (e.KeyData == Keys.Right || e.KeyData == Keys.Down && splitterFocused) { 
                        splitterDistance += SplitterIncrement;
                        if (Orientation == Orientation.Vertical) { 
                            splitterDistance = (splitterDistance + SplitterWidth > Width - Panel2MinSize -BORDERSIZE) ? splitterDistance - SplitterIncrement : splitterDistance; 
                        }
                        else { 
                            splitterDistance = (splitterDistance + SplitterWidth > Height - Panel2MinSize - BORDERSIZE) ? splitterDistance - SplitterIncrement : splitterDistance;
                        }

                    } 

                    if (!splitBegin) { 
                        splitBegin = true; 
                    }
                    //draw Helper start 
                    if (splitBegin && !splitMove) {
                        initialSplitterDistance = SplitterDistanceInternal;
                        DrawSplitBar(DRAW_START);
                    } 
                    else { //draw helper move
                        DrawSplitBar(DRAW_MOVE); 
                        //Moving by mouse .....gives the origin of the splitter.. 
                        //
                        Rectangle r = CalcSplitLine(splitterDistance, 0); 
                        int xSplit = r.X;
                        int ySplit = r.Y;
                        SplitterCancelEventArgs se = new SplitterCancelEventArgs(this.Left + SplitterRectangle.X + SplitterRectangle.Width/2, this.Top + SplitterRectangle.Y + SplitterRectangle.Height/2, xSplit, ySplit);
                        OnSplitterMoving(se); 
                        if (se.Cancel) {
                            SplitEnd(false); 
                        } 
                    }
                } //End Valid Keys.... 
            } //End SplitterFixed Check...
        }

        ///  
        /// 
        ///     Overrides the Control.OnKeydown for implementing splitter movements. 
        ///  
        protected override void OnKeyUp(KeyEventArgs e) {
            base.OnKeyUp(e); 
            if (splitBegin && IsSplitterMovable) {
                if (e.KeyData == Keys.Right || e.KeyData == Keys.Down ||
                    e.KeyData == Keys.Left || e.KeyData == Keys.Up
                    && splitterFocused) { 
                    DrawSplitBar(DRAW_END);
                    ApplySplitterDistance(); 
                    splitBegin = false; 
                    splitMove = false;
                } 
            }
            if (splitBreak) {
                splitBreak = false;
                SplitEnd(false); 
            }
            //problem with the Focus rect after Keyup .... 
            //Focus rect and reverible lines leave a trace behind on the splitter... 
            using (Graphics g = CreateGraphicsInternal()) {
                if (BackgroundImage == null) { 
                    g.FillRectangle(new SolidBrush(this.BackColor), SplitterRectangle);
                }
                DrawFocus(g, SplitterRectangle);
            } 

        } 
 
        /// 
        ///  
        ///     Overrides the Control.OnLayout.
        /// 
        protected override void OnLayout(LayoutEventArgs e) {
            SetInnerMostBorder(this); 

            if (IsSplitterMovable && !setSplitterDistance) { 
                ResizeSplitContainer(); 
            }
            base.OnLayout(e); 
        }

        /// 
        ///  
        ///     Overrides the Control.OnLostFocus to Invalidate.
        ///  
        protected override void OnLostFocus(EventArgs e) { 
            base.OnLostFocus(e);
            Invalidate(); 
        }

        /// 
        ///  
        /// Raises the  event.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override void OnMouseMove(MouseEventArgs e) {
            base.OnMouseMove(e); 
            if (!IsSplitterFixed && IsSplitterMovable) {

                //change cursor if default and user hasnt changed the cursor.
                if (Cursor == DefaultCursor && SplitterRectangle.Contains(e.Location)) 
                {
                    if (Orientation == Orientation.Vertical) { 
                        OverrideCursor = Cursors.VSplit; 
                    }
                    else { 
                        OverrideCursor = Cursors.HSplit;
                    }
                }
                else { 
                    OverrideCursor = null;;
                } 
 
                if (splitterClick) {
                    int x = e.X ; 
                    int y = e.Y ;
                    splitterDrag = true;
                    SplitMove(x, y);
                    if (Orientation == Orientation.Vertical) { 
                        x = Math.Max(Math.Min(x, Width - Panel2MinSize), Panel1MinSize);
                        y = Math.Max(y, 0); 
                    } 
                    else {
                        y = Math.Max(Math.Min(y, Height - Panel2MinSize), Panel1MinSize); 
                        x = Math.Max(x, 0);
                    }
                    Rectangle r = CalcSplitLine(GetSplitterDistance(e.X, e.Y), 0);
                    int xSplit = r.X; 
                    int ySplit = r.Y;
                    SplitterCancelEventArgs se = new SplitterCancelEventArgs(x, y, xSplit, ySplit); 
                    OnSplitterMoving(se); 
                    if (se.Cancel) {
                        SplitEnd(false); 

                    }
                }
            } 
        }
 
        ///  
        /// 
        /// Raises the  event. 
        /// 
        protected override void OnMouseLeave(EventArgs e) {
            base.OnMouseLeave(e);
            if (!Enabled) { 
                return;
            } 
            OverrideCursor = null; 
        }
 
        /// 
        /// 
        /// Raises the  event.
        ///  
        protected override void OnMouseDown(MouseEventArgs e) {
            base.OnMouseDown(e); 
            //If the Panel1MinSize + Panel2MinSize < SplitContainer.Size then carry on the splitter move... 
            if (IsSplitterMovable && SplitterRectangle.Contains(e.Location)) {
                if (!Enabled) { 
                    return;
                }
                if (e.Button == MouseButtons.Left && e.Clicks == 1 && !IsSplitterFixed) {
                    // Focus the current splitter OnMouseDown. 
                    splitterFocused = true;
                    IContainerControl c = this.ParentInternal.GetContainerControlInternal(); 
                    if (c != null) { 
                        ContainerControl cc = c as ContainerControl;
                        if (cc == null) { 
                            c.ActiveControl = this;
                        }
                        else {
                            cc.SetActiveControlInternal(this); 
                        }
                    } 
                    SetActiveControlInternal(null); 
                    nextActiveControl = panel2;
 
                    SplitBegin(e.X, e.Y);
                    splitterClick  = true;
                }
            } 
        }
 
        ///  
        /// 
        /// Raises the  event. 
        /// 
        protected override void OnMouseUp(MouseEventArgs e) {
            base.OnMouseUp(e);
            if (!Enabled) { 
                return;
            } 
            if (!IsSplitterFixed && IsSplitterMovable && splitterClick) { 
                CaptureInternal = false;
 
                if (splitterDrag) {
                    CalcSplitLine(GetSplitterDistance(e.X, e.Y), 0);
                    SplitEnd(true);
                } 
                else {
                    SplitEnd(false); 
 
                }
                splitterClick  = false; 
                splitterDrag = false;
            }
        }
 
	/// 
 	///     Overrides the Control.OnMove() to synchronize the 
 	///     splitterRect with the position of the SplitContainer. 
	/// 
 	protected override void OnMove(EventArgs e) 
	{
	    base.OnMove(e);
	    SetSplitterRect(this.Orientation == Orientation.Vertical);
 	} 
		
 
        ///  
        /// 
        ///     Overrides the Control.OnPaint() to focus the Splitter. 
        /// 
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
            if (Focused) { 
                DrawFocus(e.Graphics,SplitterRectangle);
            } 
        } 

        ///  
        /// 
        ///     Inherriting classes should override this method to respond to the
        ///     splitterMoving event. This event occurs while the splitter is
        ///     being moved by the user. 
        /// 
        public void OnSplitterMoving(SplitterCancelEventArgs e) { 
            SplitterCancelEventHandler handler = (SplitterCancelEventHandler)Events[EVENT_MOVING]; 
            if (handler != null) handler(this, e);
 
        }

        /// 
        ///  
        ///     Inherriting classes should override this method to respond to the
        ///     splitterMoved event. This event occurs when the user finishes 
        ///     moving the splitter. 
        /// 
        public void OnSplitterMoved(SplitterEventArgs e) { 
            SplitterEventHandler handler = (SplitterEventHandler)Events[EVENT_MOVED];
            if (handler != null) handler(this, e);
        }
 
        ////////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                                            // 
        ///END DELEGATES                                                                              // 
        //                                                                                            //
        //////////////////////////////////////////////////////////////////////////////////////////////// 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override void OnRightToLeftChanged(EventArgs e) { 
            base.OnRightToLeftChanged(e);
            // pass the RightToLeft value to the Parent. 
            this.panel1.RightToLeft = this.RightToLeft;
            this.panel2.RightToLeft = this.RightToLeft;
            UpdateSplitter();
        } 

 
        //////////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                                            //
        ///START PRIVATE FUNCTIONS                                                                    // 
        //                                                                                            //
        ////////////////////////////////////////////////////////////////////////////////////////////////

 
        /// 
        ///  
        ///     Sets the split position to be the current split size. This is called 
        ///     by splitEdit
        ///  
        /// 
        private void ApplySplitterDistance() {

            using (new System.Windows.Forms.Layout.LayoutTransaction(this, this, "SplitterDistance", false)) { 
                SplitterDistanceInternal = splitterDistance;
            } 
 
            // Refer to VsWhidbey : 467815: We need to invalidate when we have transparent backgournd.
            if (this.BackColor == Color.Transparent) { 
                // the panel1 retains the focus rect... so Invalidate the rect ...
                Invalidate();
            }
 
            if (Orientation == Orientation.Vertical) {
 
                if (RightToLeft == RightToLeft.No) { 
                    splitterRect.X = this.Location.X + SplitterDistanceInternal;
                } 
                else {
                    splitterRect.X = this.Right - SplitterDistanceInternal - SplitterWidthInternal;
                }
            } 
            else {
                splitterRect.Y = this.Location.Y + SplitterDistanceInternal; 
            } 
        }
 
        /// 
        /// 
        ///     Calculates the bounding rect of the split line. minWeight refers
        ///     to the minimum height or width of the splitline. 
        /// 
        private Rectangle CalcSplitLine(int splitSize, int minWeight) { 
 
           Rectangle r = new Rectangle();
            switch (Orientation) { 
                case Orientation.Vertical:
                    r.Width =  SplitterWidthInternal ;
                    r.Height = Height;
                    if (r.Width < minWeight) { 
                        r.Width = minWeight;
                    } 
 
                    if (RightToLeft == RightToLeft.No) {
                        r.X = panel1.Location.X + splitSize; 
                    }
                    else {
                        r.X = Width - splitSize - SplitterWidthInternal;
                    } 

                    break; 
 

                case Orientation.Horizontal: 
                    r.Width = Width;
                    r.Height = SplitterWidthInternal;
                    if (r.Width < minWeight) {
                        r.Width = minWeight; 
                    }
                    r.Y = panel1.Location.Y + splitSize; 
                    break; 
            }
            return r; 
        }

        /// 
        ///  
        ///     Draws the splitter bar at the current location. Will automatically
        ///     cleanup anyplace the splitter was drawn previously. 
        ///  
        /// 
        private void DrawSplitBar(int mode) { 
            if (mode != DRAW_START && lastDrawSplit != -1) {
                DrawSplitHelper(lastDrawSplit);
                lastDrawSplit = -1;
            } 
            // Bail if drawing with no old point...
            // 
            else if (mode != DRAW_START && lastDrawSplit == -1) { 
                return;
            } 

            if (mode != DRAW_END) {
                if (splitMove || splitBegin) { // Splitter is moved by keys and not by mouse
                        DrawSplitHelper(splitterDistance); 
                        lastDrawSplit = splitterDistance;
                } 
                else { 
                    DrawSplitHelper(splitterDistance);
                    lastDrawSplit = splitterDistance; 
                }

            }
            else { 
                if (lastDrawSplit != -1) {
                    DrawSplitHelper(lastDrawSplit); 
                } 
                lastDrawSplit = -1;
            } 
        }

        /// 
        ///     
        ///       Draws the focus rectangle if the control has focus.
        /// 
        ///     
        /// 
        private void DrawFocus(Graphics g, Rectangle r) { 
            r.Inflate (-1, -1);
            ControlPaint.DrawFocusRectangle(g, r, this.ForeColor, this.BackColor);
        }
 
        /// 
        ///  
        ///     Draws the splitter line at the requested location. Should only be called 
        ///     by drawSpltBar.
        ///  
        /// 
        private void DrawSplitHelper(int splitSize) {

            Rectangle r = CalcSplitLine(splitSize, 3); 
            IntPtr parentHandle = this.Handle;
            IntPtr dc = UnsafeNativeMethods.GetDCEx(new HandleRef(this, parentHandle), NativeMethods.NullHandleRef, NativeMethods.DCX_CACHE | NativeMethods.DCX_LOCKWINDOWUPDATE); 
            IntPtr halftone = ControlPaint.CreateHalftoneHBRUSH(); 
            IntPtr saveBrush = SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, halftone));
            SafeNativeMethods.PatBlt(new HandleRef(this, dc), r.X, r.Y, r.Width, r.Height, NativeMethods.PATINVERT); 
            SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, saveBrush));
            SafeNativeMethods.DeleteObject(new HandleRef(null, halftone));
            UnsafeNativeMethods.ReleaseDC(new HandleRef(this, parentHandle), new HandleRef(null, dc));
        } 

        ///  
        ///  
        ///     Calculates the split size based on the mouse position (x, y).
        ///  
        /// 
        private int GetSplitterDistance(int x, int y) {
            int delta;
            if (Orientation == Orientation.Vertical) { 
                delta = x - anchor.X;
            } 
            else { 
                delta = y - anchor.Y;
            } 

            // Negative delta - moving to the left
            // Positive delta - moving to the right
 
            int size = 0;
            switch (Orientation) { 
                case Orientation.Vertical: 
                    if (RightToLeft == RightToLeft.No) {
                        size = Math.Max(panel1.Width + delta, BORDERSIZE); 
                    }
                    else {
                        // In RTL negative delta actually means increasing the size....
                        size = Math.Max(panel1.Width - delta, BORDERSIZE); 
                    }
                    break; 
                case Orientation.Horizontal: 
                    size = Math.Max(panel1.Height + delta, BORDERSIZE);
                    break; 
            }
            if (Orientation == Orientation.Vertical) {
                return Math.Max(Math.Min(size, Width - Panel2MinSize), Panel1MinSize);
            } 
            else {
                return Math.Max(Math.Min(size, Height - Panel2MinSize), Panel1MinSize); 
            } 
        }
 
        /// 
        ///     Process an arrowKey press by selecting the next control in the group
        ///     that the activeControl belongs to.
        ///  
        /// 
        private bool ProcessArrowKey(bool forward) { 
            Control group = this; 
            if (ActiveControl != null) {
                group = ActiveControl.ParentInternal; 
            }
            return group.SelectNextControl(ActiveControl, forward, false, false, true);
        }
 
        /// 
        ///  
        ///     Re paint SplitterRect for SplitContainer 
        /// 
        ///  
        private void RepaintSplitterRect()
        {
            if (IsHandleCreated) {
                Graphics g = this.CreateGraphicsInternal(); 
                if (BackgroundImage != null) {
 
                    using (TextureBrush textureBrush = new TextureBrush(BackgroundImage,WrapMode.Tile)) { 
                        g.FillRectangle(textureBrush, ClientRectangle);
                    } 
                }
                else{
                    g.FillRectangle(new SolidBrush(this.BackColor), splitterRect);
                } 
                g.Dispose();
            } 
        } 

 
        private void SetSplitterRect(bool vertical) {
            if (vertical)
            {
                splitterRect.X = ((RightToLeft == RightToLeft.Yes) ? this.Width - splitterDistance - SplitterWidthInternal : this.Location.X + splitterDistance); 
                splitterRect.Y = this.Location.Y;
                splitterRect.Width = SplitterWidthInternal; 
                splitterRect.Height = this.Height; 
            }
            else 
            {
                splitterRect.X = this.Location.X;
                splitterRect.Y = this.Location.Y + SplitterDistanceInternal;
                splitterRect.Width = this.Width; 
                splitterRect.Height = SplitterWidthInternal;
            } 
        } 

        ///  
        /// 
        ///     Reize SplitContainer
        /// 
        ///  
        private void ResizeSplitContainer()
        { 
            if (splitContainerScaling) 
            {
                return; 
            }

            panel1.SuspendLayout();
            panel2.SuspendLayout(); 

            if (this.Width == 0) {         // Set the correct Width iif the WIDTH has changed to ZERO. 
                panel1.Size = new Size(0, panel1.Height); 
                panel2.Size = new Size(0, panel2.Height);
            } 
            else if (this.Height == 0) {   // Set the correct Height iif the HEIGHT has changed to ZERO.
                panel1.Size = new Size(panel1.Width, 0);
                panel2.Size = new Size(panel2.Width, 0);
            } 
            else
            { 
                if (Orientation == Orientation.Vertical) 
                {
                    // If no panel is collapsed then do the default ... 
                    if (!CollapsedMode)
                    {
                        if (this.FixedPanel == FixedPanel.Panel1) {
                            panel1.Size = new Size(panelSize, Height); 
                            panel2.Size = new Size(Math.Max(Width - panelSize - SplitterWidthInternal, Panel2MinSize), Height);
                        } 
                        if (this.FixedPanel == FixedPanel.Panel2) { 
                            panel2.Size = new Size(panelSize, Height);
                            splitterDistance = Math.Max(Width - panelSize - SplitterWidthInternal, Panel1MinSize); 
                            panel1.WidthInternal = splitterDistance;
                            panel1.HeightInternal = Height;
                        }
                        if (this.FixedPanel == FixedPanel.None) { 
                            if (ratioWidth != 0.0) {
                                splitterDistance = Math.Max((int)(Math.Floor(this.Width / ratioWidth)), Panel1MinSize); 
                            } 
                            panel1.WidthInternal = splitterDistance; //Default splitter distance from left or top.
                            panel1.HeightInternal = Height; 
                            panel2.Size = new Size(Math.Max(Width - splitterDistance - SplitterWidthInternal, Panel2MinSize), Height);
                        }
                        if (RightToLeft == RightToLeft.No) {
                            panel2.Location = new Point(panel1.WidthInternal + SplitterWidthInternal, 0); 
                        }
                        else { 
                            panel1.Location = new Point(Width - panel1.WidthInternal, 0); 
                        }
                        RepaintSplitterRect(); 
                        SetSplitterRect(true);
                    }
                    else
                    { 
                        if (Panel1Collapsed) {
                            panel2.Size = this.Size; 
                            panel2.Location = new Point(0,0); 
                        }
                        else if (Panel2Collapsed) { 
                            panel1.Size = this.Size;
                            panel1.Location = new Point(0,0);
                        }
                    } 

                } 
                else if (Orientation == Orientation.Horizontal) { 
                    // If no panel is collapsed then do the default ...
                    if (!CollapsedMode) 
                    {
                        if (this.FixedPanel == FixedPanel.Panel1) {

                            //Default splitter distance from left or top. 
                            panel1.Size = new Size(Width, panelSize);
                            int panel2Start = panelSize + SplitterWidthInternal; 
                            panel2.Size = new Size(Width, Math.Max(Height - panel2Start, Panel2MinSize)); 
                            panel2.Location = new Point(0,panel2Start);
                        } 
                        if (this.FixedPanel == FixedPanel.Panel2) {

                            panel2.Size = new Size(Width, panelSize);
                            splitterDistance = Math.Max(Height - Panel2.Height - SplitterWidthInternal, Panel1MinSize); 
                            panel1.HeightInternal = splitterDistance;
                            panel1.WidthInternal = Width; 
                            int panel2Start = splitterDistance + SplitterWidthInternal; 
                            panel2.Location = new Point(0, panel2Start);
                        } 
                        if (this.FixedPanel == FixedPanel.None) {
                            //NO PANEL FIXED !!
                            if (ratioHeight != 0.0)
                            { 
                                splitterDistance = Math.Max((int)(Math.Floor(this.Height / ratioHeight )), Panel1MinSize);
                            } 
                            panel1.HeightInternal = splitterDistance; //Default splitter distance from left or top. 
                            panel1.WidthInternal = Width;
                            int panel2Start = splitterDistance + SplitterWidthInternal; 
                            panel2.Size = new Size(Width,Math.Max(Height - panel2Start, Panel2MinSize));
                            panel2.Location = new Point(0,panel2Start);

 
                        }
                        RepaintSplitterRect(); 
                        SetSplitterRect(false); 
                    }
                    else 
                    {
                        if (Panel1Collapsed) {
                            panel2.Size = this.Size;
                            panel2.Location = new Point(0,0); 
                        }
                        else if (Panel2Collapsed) { 
                            panel1.Size = this.Size; 
                            panel1.Location = new Point(0,0);
                        } 
                    }
                }
                try {
                    resizeCalled = true; 
                    ApplySplitterDistance();
                } 
                finally { 
                    resizeCalled = false;
                } 
            }
            panel1.ResumeLayout();
            panel2.ResumeLayout();
        } 

 
        ///  
        ///     Scales an individual control's location, size, padding and margin.
        ///     If the control is top level, this will not scale the control's location. 
        ///     This does not scale children or the size of auto sized controls.  You can
        ///     omit scaling in any direction by changing BoundsSpecified.
        ///
        ///     After the control is scaled the RequiredScaling property is set to 
        ///     BoundsSpecified.None.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override void ScaleControl(SizeF factor, BoundsSpecified specified) {
            try 
            {
                splitContainerScaling = true;
                base.ScaleControl(factor, specified);
 
                float scale;
                if (orientation == Orientation.Vertical) { 
                    scale = factor.Width; 
                }
                else { 
                    scale = factor.Height;
                }
                SplitterWidth = (int)Math.Round((float)SplitterWidth * scale);
            } 
            finally
            { 
                splitContainerScaling = false; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        protected override void Select(bool directed, bool forward) { 
            // avoid re-entrant code. 
            // SelectNextControl can call back on us.. and we might end up infinitely recursing.
            if (selectNextControl) 
            {
                return;
            }
            // continue selection iff panels have controls or tabstop is true. 
            if ((this.Panel1.Controls.Count > 0 || this.Panel2.Controls.Count > 0) || tabStop) {
                SelectNextControlInContainer(this, forward, true, true, false); 
            } 
            else { //If this SplitContainer cannot be selected let the parent select the next in line
                Control parent = this.ParentInternal; 
                if (parent != null)
                {
                    try
                    { 
                    	selectNextControl = true;
                    	parent.SelectNextControl(this, forward, true, true, true); 
                    } 
                    finally
                    { 
                    	selectNextControl = false;
                    }
                }
            } 
        }
 
        ///  
        /// 
        ///     Selects the next control following ctl. 
        /// 
        private bool SelectNextControlInContainer(Control ctl, bool forward, bool tabStopOnly,
                                      bool nested, bool wrap) {
            if (!Contains(ctl) || !nested && ctl.ParentInternal != this) ctl = null; 
            Control start = ctl;
            SplitterPanel firstPanel = null; 
            do { 
                ctl = GetNextControl(ctl, forward);
 
                SplitterPanel panel = ctl as SplitterPanel;
                if (panel != null && panel.Visible) {
                    //We have crossed over to the second Panel...
                    if (firstPanel != null) { 
                        break;
                    } 
                    firstPanel = panel; 
                }
                if (!forward && firstPanel != null && ctl.ParentInternal != firstPanel) { 
                    //goback to start correct re-ordering ....
                    ctl = firstPanel;
                    break;
                } 
                if (ctl == null) {
                    break; 
                } 
                else {
                    if (ctl.CanSelect && ctl.TabStop) { 
                        if (ctl is SplitContainer)
                        {
                            ((SplitContainer)ctl).Select(forward, forward);
                        } 
                        else
                        { 
                            SelectNextActiveControl(ctl, forward, tabStopOnly, nested, wrap); 
                        }
                        return true; 
                    }
                }
            } while (ctl != null);
            if (ctl != null && this.TabStop) { 
                //we are on Splitter.....Focus it
                splitterFocused = true; 
                IContainerControl c = this.ParentInternal.GetContainerControlInternal(); 
                if (c != null) {
                    ContainerControl cc = c as ContainerControl; 
                    if (cc == null) {
                        c.ActiveControl = this;
                    }
                    else { 
                        IntSecurity.ModifyFocus.Demand();
                        cc.SetActiveControlInternal(this); 
                    } 
                }
                SetActiveControlInternal(null); 
                nextActiveControl = ctl;
                return true;
            }
            else 
            {
                // If the splitter cannot be selected select the next control in the splitter 
                bool selected = SelectNextControlInPanel(ctl, forward, tabStopOnly, nested, wrap); 
                if (!selected)
                { 
                    Control parent = this.ParentInternal;
                    if (parent != null)
                    {
                        try 
                        {
                            selectNextControl = true; 
                            parent.SelectNextControl(this, forward, true, true, true); 
                        }
                        finally 
                        {
                            selectNextControl = false;
                        }
                    } 
                }
            } 
            return false; 
        }
 
        /// 
        /// 
        ///     Selects the next control following ctl.
        ///  
        [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
        private bool SelectNextControlInPanel(Control ctl, bool forward, bool tabStopOnly, 
                                      bool nested, bool wrap) { 

            if (!Contains(ctl) || !nested && ctl.ParentInternal != this) ctl = null; 
            Control start = ctl;
            do {
                ctl = GetNextControl(ctl, forward);
                if (ctl == null || (ctl is SplitterPanel && ctl.Visible)) { 
                    break;
                } 
                else { 
                    if (ctl.CanSelect && (!tabStopOnly || ctl.TabStop)) {
                        if (ctl is SplitContainer) 
                        {
                            ((SplitContainer)ctl).Select(forward, forward);
                        }
                        else 
                        {
                            SelectNextActiveControl(ctl, forward, tabStopOnly, nested, wrap); 
                        } 
                        return true;
                    } 
                }
            } while (ctl != null);

            //If CTL == null .. we r out of the Current SplitContainer... 
            if (ctl == null || (ctl is SplitterPanel && !ctl.Visible)) {
                callBaseVersion = true; 
 
            }
            //IF the CTL == typeof(SpliterPanel) find the NEXT Control... so that we know 
            // we can focus the NEXT control within this SPLITCONTAINER....
            else
            {
                ctl = GetNextControl(ctl, forward); 
                if (forward) {
                    nextActiveControl = panel2; 
                } 
                else {
                    if (ctl == null || !(ctl.ParentInternal.Visible)) { 
                        callBaseVersion = true;
                    }
                    else
                        nextActiveControl = panel2; 
                }
            } 
            return false; 
        }
 
        // This will select the correct active control in the containerControl (if the passed in control is a containerControl)
        private static void SelectNextActiveControl(Control ctl, bool forward, bool tabStopOnly, bool nested, bool wrap)
        {
            ContainerControl container = ctl as ContainerControl; 
            if (container != null)
            { 
                bool correctParentActiveControl = true; 
                if (container.ParentInternal != null)
                { 
                    IContainerControl c = container.ParentInternal.GetContainerControlInternal();
                    if (c != null)
                    {
                        c.ActiveControl = container; 
                        correctParentActiveControl = (c.ActiveControl == container);
                    } 
                } 
                if (correctParentActiveControl)
                { 
                    ctl.SelectNextControl(null, forward, tabStopOnly, nested, wrap);
                }
            }
            else 
            {
                ctl.Select(); 
            } 
        }
 
        /// 
        /// 
        ///     Selects the innermost PANEL.
        ///  
        private void SetInnerMostBorder(SplitContainer sc) {
            foreach(Control ctl in sc.Controls) { 
                bool foundChildSplitContainer = false; 
                if (ctl is SplitterPanel) {
                    foreach (Control c in ctl.Controls) { 
                        SplitContainer c1 = c as SplitContainer;
                        if (c1 != null && c1.Dock == DockStyle.Fill) {
                           // We need to Overlay borders
                           // if the Children have matching BorderStyles ... 
                           if (c1.BorderStyle != BorderStyle) {
                               break; 
                           } 
                           ((SplitterPanel)ctl).BorderStyle = BorderStyle.None;
                           SetInnerMostBorder(c1); 
                           foundChildSplitContainer = true;
                        }
                    }
                    if (!foundChildSplitContainer) { 
                        ((SplitterPanel)ctl).BorderStyle = BorderStyle;
                    } 
                } 
            }
        } 


        /// 
        ///  
        ///     This protected override allows us to check is an unvalid value is set for Width and Height.
        ///     The SplitContainer would not throw on invalid Size (i.e Width and Height) settings, but would correct the error like Form 
        ///     Say, the Panel1MinSize == 150 , Panel2MinSize == 50 and SplitterWidth == 4 and the user tries 
        ///     to set SplitContainer.Width = 50 ... then this function would try to correct the value to 204.. instead of throwing.
        ///  
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {

            // If we are changing Height, check if its greater than minimun else ... make it equal to the minimum
            if ((specified & BoundsSpecified.Height) != BoundsSpecified.None && Orientation == Orientation.Horizontal) { 
                if (height < Panel1MinSize + SplitterWidthInternal + Panel2MinSize)
                { 
                    height = Panel1MinSize + SplitterWidthInternal + Panel2MinSize; 
                }
            } 

            // If we are changing Width, check if its greater than minimun else ... make it equal to the minimum
            if ((specified & BoundsSpecified.Width) != BoundsSpecified.None && Orientation == Orientation.Vertical) {
                if (width < Panel1MinSize + SplitterWidthInternal + Panel2MinSize) 
                {
                    width = Panel1MinSize + SplitterWidthInternal + Panel2MinSize; 
                } 
            }
 
            base.SetBoundsCore(x, y, width, height, specified);

            SetSplitterRect(this.Orientation == Orientation.Vertical);
        } 

        ///  
        ///  
        ///     Begins the splitter moving.
        ///  
        /// 
        private void SplitBegin(int x, int y) {
            anchor = new Point(x, y);
            splitterDistance = GetSplitterDistance(x, y); 
            initialSplitterDistance = splitterDistance;
            initialSplitterRectangle = SplitterRectangle; 
 
            // SECREVIEW : We need a message filter to capture the ESC key
            //           to cancel the split action. 
            //           The method PreFilterMessage is adorned with a LinkDemand.
            //           But this is not enough since this is a public unsealed class.
            //           We should have private implementation of the IMessageFilter
            //           So that we dont expose this to the classed deriving from this public class 
            //           Refer to VsWhidbey : 423553 for more information.
            IntSecurity.UnmanagedCode.Assert(); 
            try { 
                if (splitContainerMessageFilter == null)
                { 
                   splitContainerMessageFilter = new SplitContainerMessageFilter(this);
                }
                Application.AddMessageFilter(splitContainerMessageFilter);
            } 
            finally {
                CodeAccessPermission.RevertAssert(); 
            } 
            CaptureInternal = true;
            DrawSplitBar(DRAW_START); 
        }

        /// 
        ///  
        ///     The split movement.
        ///  
        ///  
        private void SplitMove(int x, int y) {
            int size = GetSplitterDistance(x, y); 
            int delta = size - initialSplitterDistance;
            int mod = delta % SplitterIncrement;
            if (splitterDistance != size) {
                if (Orientation == Orientation.Vertical) 
                {
                	if (size + SplitterWidthInternal <= this.Width - Panel2MinSize - BORDERSIZE) 
                	{ 
                		splitterDistance = size - mod;
                	} 
                }
                else
                {
                	if (size + SplitterWidthInternal <= this.Height - Panel2MinSize - BORDERSIZE) 
                	{
                		splitterDistance = size - mod; 
                	} 
                }
            } 
            DrawSplitBar(DRAW_MOVE);
        }

        ///  
        /// 
        ///     Finishes the split movement. 
        ///  
        /// 
        private void SplitEnd(bool accept) { 
            DrawSplitBar(DRAW_END);
            if (splitContainerMessageFilter != null)
            {
                Application.RemoveMessageFilter(splitContainerMessageFilter); 
                splitContainerMessageFilter = null;
            } 
 
            if (accept) {
                ApplySplitterDistance(); 

            }
            else if (splitterDistance != initialSplitterDistance) {
                splitterClick = false; 
                splitterDistance = SplitterDistanceInternal = initialSplitterDistance;
            } 
            anchor = Point.Empty; 

        } 

        /// 
        /// 
        ///     Update Splitter 
        /// 
        ///  
        private void UpdateSplitter() { 
            if (splitContainerScaling)
            { 
                return;
            }
            panel1.SuspendLayout();
            panel2.SuspendLayout(); 
            if (Orientation == Orientation.Vertical) {
                bool isRTL = RightToLeft == RightToLeft.Yes; 
 
                //NO PANEL FIXED !!
                if (!CollapsedMode) { 

                    panel1.HeightInternal = Height;
                    panel1.WidthInternal = splitterDistance; //Default splitter distance from left or top.
                    panel2.Size = new Size(Width - splitterDistance - SplitterWidthInternal, Height); 

                    if (!isRTL) { 
                        panel1.Location = new Point(0,0); 
                        panel2.Location = new Point(splitterDistance + SplitterWidthInternal, 0);
                    } 
                    else {
                        panel1.Location = new Point(Width - splitterDistance, 0);
                        panel2.Location = new Point(0, 0);
                    } 

                    RepaintSplitterRect(); 
                    SetSplitterRect(true /*Vertical*/); 
                    if (!resizeCalled) {
                        ratioWidth =  ((double)(this.Width) / (double)(panel1.Width) > 0) ? (double)(this.Width) / (double)(panel1.Width) : ratioWidth; 
                    }


                } 
                else {
                    if (Panel1Collapsed) { 
                        panel2.Size = this.Size; 
                        panel2.Location = new Point(0,0);
                    } 
                    else if (Panel2Collapsed) {
                        panel1.Size = this.Size;
                        panel1.Location = new Point(0,0);
                    } 
                    // Update Ratio when the splitContainer is in CollapsedMode.
                    if (!resizeCalled) 
                    { 
                    	ratioWidth = ((double)(this.Width) / (double)(splitterDistance) > 0) ? (double)(this.Width) / (double)(splitterDistance) : ratioWidth;
                    } 
                }
            }
            else {
                //NO PANEL FIXED !! 
                if (!CollapsedMode) {
                    panel1.Location = new Point(0,0); 
                    panel1.WidthInternal = Width; 

                    panel1.HeightInternal = SplitterDistanceInternal; //Default splitter distance from left or top. 
                    int panel2Start = splitterDistance + SplitterWidthInternal;
                    panel2.Size = new Size(Width, Height - panel2Start);
                    panel2.Location = new Point(0,panel2Start);
 
                    RepaintSplitterRect();
                    SetSplitterRect(false/*Horizontal*/); 
 
                    if (!resizeCalled) {
                        ratioHeight =  ((double)(this.Height) / (double)(panel1.Height) > 0) ? (double)(this.Height) / (double)(panel1.Height) : ratioHeight; 
                    }
                }
                else {
                    if (Panel1Collapsed) { 
                        panel2.Size = this.Size;
                        panel2.Location = new Point(0,0); 
                    } 
                    else if (Panel2Collapsed) {
                        panel1.Size = this.Size; 
                        panel1.Location = new Point(0,0);
                    }

                    // Update Ratio when the splitContainer is in CollapsedMode. 
                    if (!resizeCalled)
                    { 
                    	ratioHeight = ((double)(this.Height) / (double)(splitterDistance) > 0) ? (double)(this.Height) / (double)(splitterDistance) : ratioHeight; 
                    }
                } 
            }
            panel1.ResumeLayout();
            panel2.ResumeLayout();
         } 

        ///  
        ///  
        ///     Handles the WM_SETCURSOR message
        ///  
        /// 
        private void WmSetCursor(ref Message m) {

            // Accessing through the Handle property has side effects that break this 
            // logic. You must use InternalHandle.
            // 
            if (m.WParam == InternalHandle && ((int)m.LParam & 0x0000FFFF) == NativeMethods.HTCLIENT) { 
                if (OverrideCursor != null) {
                    Cursor.CurrentInternal = OverrideCursor; 
                }
                else {
                    Cursor.CurrentInternal = Cursor;
                } 
            }
            else { 
                DefWndProc(ref m); 
            }
 
        }

        ///////////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                                               // 
        // END PRIVATE FUNCTIONS ...                                                                     //
        //                                                                                               // 
        /////////////////////////////////////////////////////////////////////////////////////////////////// 

 


        ///////////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                                               // 
        // Start PROTECTED OVERRIDE FUNCTIONS                                                            //
        //                                                                                               // 
        /////////////////////////////////////////////////////////////////////////////////////////////////// 

        internal override void AfterControlRemoved(Control control, Control oldParent) { 
            base.AfterControlRemoved(control, oldParent);
            if (control is SplitContainer && control.Dock == DockStyle.Fill)
            {
               SetInnerMostBorder(this); 
            }
 
        } 

        ///  
        /// 
        /// 
        ///    Processes a dialog key. Overrides Control.processDialogKey(). This
        ///    method implements handling of the TAB, LEFT, RIGHT, UP, and DOWN 
        ///    keys in dialogs.
        ///    The method performs no processing on keys that include the ALT or 
        ///    CONTROL modifiers. For the TAB key, the method selects the next control 
        ///    on the form. For the arrow keys,
        ///    !!! 
        /// 
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
        protected override bool ProcessDialogKey(Keys keyData) {
#if DEBUG 
            Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "ContainerControl.ProcessDialogKey [" + keyData.ToString() + "]");
#endif 
            if ((keyData & (Keys.Alt | Keys.Control)) == Keys.None) { 
                Keys keyCode = (Keys)keyData & Keys.KeyCode;
                switch (keyCode) { 
                    case Keys.Tab:
                        if (ProcessTabKey((keyData & Keys.Shift) == Keys.None)) return true;
                        break;
                    case Keys.Left: 
                    case Keys.Right:
                    case Keys.Up: 
                    case Keys.Down: 
                        if (!splitterFocused) {
                            if (ProcessArrowKey(keyCode == Keys.Right || 
                                            keyCode == Keys.Down)) return true;
                        }
                        else
                            return false; 
                        break;
 
                } 
            }
            return base.ProcessDialogKey(keyData); 
        }

        /// 
        /// ///  
        ///   This will process the TabKey for the SplitContainer. The Focus needs to Shift from controls to the Left of the Splitter
        ///   to the splitter and then to the controls on the right of the splitter. This override implements this Logic. 
        ///  
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
        protected override bool ProcessTabKey(bool forward) { 
            //Dont Focus the Splitter if TabStop == False or if the Splitter is Fixed !!
            if (!tabStop || IsSplitterFixed) {
                return base.ProcessTabKey(forward);
            } 

            if (nextActiveControl != null) { 
                SetActiveControlInternal(nextActiveControl); 
                nextActiveControl = null;
            } 

            if (SelectNextControlInPanel(ActiveControl, forward, true, true, true)) {
                nextActiveControl = null;
                splitterFocused = false; 
                return true;
            } 
            else { 
                if (callBaseVersion) {
                    callBaseVersion = false; 
                    return base.ProcessTabKey(forward);
                }
                else {
                    //We are om Splitter ...... 
                    splitterFocused = true;
                    IContainerControl c = this.ParentInternal.GetContainerControlInternal(); 
                    if (c != null) { 
                        ContainerControl cc = c as ContainerControl;
                        if (cc == null) { 
                            c.ActiveControl = this;
                        }
                        else {
                            cc.SetActiveControlInternal(this); 
                        }
                    } 
                    SetActiveControlInternal(null); 
                    return true;
                } 
            }
        }

        protected override void OnMouseCaptureChanged(EventArgs e) { 
            base.OnMouseCaptureChanged(e);
            if (splitContainerMessageFilter != null) 
            { 
                Application.RemoveMessageFilter(splitContainerMessageFilter);
                splitContainerMessageFilter = null; 
            }
        }

        ///  
        /// 
        ///  
        ///  
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message msg) { 
            switch (msg.Msg) {
                case NativeMethods.WM_SETCURSOR:
                    WmSetCursor(ref msg);
                    break; 
                case NativeMethods.WM_SETFOCUS:
                    splitterFocused = true; 
                    base.WndProc(ref msg); 
                    break;
                case NativeMethods.WM_KILLFOCUS: 
                    splitterFocused = false;
                    base.WndProc(ref msg);
                    break;
 
                default:
                    base.WndProc(ref msg); 
                    break; 
            }
        } 


        /// 
        ///  
        /// 
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override Control.ControlCollection CreateControlsInstance() {
            return new SplitContainerTypedControlCollection(this, typeof(SplitterPanel), /*isReadOnly*/true); 
        }


        /////////////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                                 //
        // End   PROTECTED OVERRIDE FUNCTIONS                                              // 
        //                                                                                 // 
        ///////////////////////////////////////////////////////////////////////////////////////////////////
 

        private class SplitContainerMessageFilter : IMessageFilter
        {
            private SplitContainer owner = null; 

            public SplitContainerMessageFilter(SplitContainer splitContainer) 
            { 
                this.owner = splitContainer;
            } 

            /// 
            /// 
            ///  
            /// 
            [ 
            System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 
            ]
            bool IMessageFilter.PreFilterMessage(ref Message m) { 
                if (m.Msg >= NativeMethods.WM_KEYFIRST && m.Msg <= NativeMethods.WM_KEYLAST) {
                    if ((m.Msg == NativeMethods.WM_KEYDOWN && (int)m.WParam == (int)Keys.Escape)
                        || (m.Msg == NativeMethods.WM_SYSKEYDOWN)) {
                        //Notify that splitMOVE was reverted .. 
                        //this is used in ONKEYUP!!
                        owner.splitBegin = false; 
                        owner.SplitEnd(false); 
                        owner.splitterClick  = false;
                        owner.splitterDrag = false; 
                    }
                    return true;
                }
                return false; 
            }
        } 
 
         /// 
         /// This control collection only allows a specific type of control 
         /// into the controls collection.  It optionally supports readonlyness.
         /// 
         internal class SplitContainerTypedControlCollection : WindowsFormsUtils.TypedControlCollection {
            SplitContainer owner; 

            public SplitContainerTypedControlCollection(Control c, Type type, bool isReadOnly): base(c, type, isReadOnly) 
            { 
              this.owner = c as SplitContainer;
            } 

            public override void Remove(Control value) {
                if (value is SplitterPanel) {
                    if (!owner.DesignMode) { 
                        if (IsReadOnly) throw new NotSupportedException(SR.GetString(SR.ReadonlyControlsCollection));
                    } 
                } 
                base.Remove(value);
            } 

            internal override void SetChildIndexInternal(Control child, int newIndex)
            {
               if (child is SplitterPanel) { 
                   if (!owner.DesignMode) {
                       if (IsReadOnly) { 
                           throw new NotSupportedException(SR.GetString(SR.ReadonlyControlsCollection)); 
                       }
                   } 
                   else {
                       // just no-op it at DT.
                       return;
                   } 
               }
               base.SetChildIndexInternal(child, newIndex); 
            } 

        } 

    }
 }

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
namespace System.Windows.Forms {
 
    using Microsoft.Win32;
    using System;
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Diagnostics.CodeAnalysis;
    using System.Drawing; 
    using System.Runtime.InteropServices; 
    using System.Runtime.Remoting;
    using System.Security; 
    using System.Security.Permissions;
    using System.Windows.Forms;
    using System.Collections;
    using System.Drawing.Drawing2D; 
    using System.Globalization;
 
    ///  
    /// 
    ///    A SplitContainer is a ContainerControl with 2 panels separated with a splitter 
    ///    in the middle. This is a composite control. The user can drag and drop this control from Toolbox.
    ///    Controls can be added to the right panel and the left panel. The Orientation can be either Horizontal or Vertical.
    ///    The Controls inside the Panels would be redrawn with the new Orientation.
    ///    With this control the user need be aware of docking, z-order of the controls. The controls get parented when thry are 
    ///    dropped on the SpitContainer.
    ///  
    [ 
    ComVisible(true),
    ClassInterface(ClassInterfaceType.AutoDispatch), 
    DefaultEvent("SplitterMoved"),
    Docking(DockingBehavior.AutoDock),
    Designer("System.Windows.Forms.Design.SplitContainerDesigner, " + AssemblyRef.SystemDesign),
    SRDescription(SR.DescriptionSplitContainer) 
    ]
    public class SplitContainer : ContainerControl 
    { 

        // 
        // CONTANTS USED DURING DRAWING SPLITTER MOOVEMENTS
        //
        private const int DRAW_START = 1;
        private const int DRAW_MOVE = 2; 
        private const int DRAW_END = 3;
        private const int rightBorder = 5; 
        private const int leftBorder = 2; 

        private int BORDERSIZE = 0; 


        //
        // SplitContainer private Cached copies of public properties... 
        //
        private Orientation orientation = Orientation.Vertical; 
        private SplitterPanel panel1 = null; 
        private SplitterPanel panel2 = null;
        private BorderStyle borderStyle = System.Windows.Forms.BorderStyle.None; 
        private FixedPanel fixedPanel = FixedPanel.None;

        private int panel1MinSize = 25; //Panel1 Minimum Size
        private int panel2MinSize = 25; //Panel2 Minimum Size 
        private bool tabStop = true;
        // 
        //Fixed panel width or height; 
        //
        private int panelSize; 

        //
        //SPLITTER PROPERTIES
        // 
        private Rectangle splitterRect;
        private int splitterInc = 1; 
        private bool splitterFixed; 
        private int splitterDistance = 50; //default splitter distance;
        private int splitterWidth = 4; 
        private int splitDistance = 50;

        //
        //Properties used using DRAWING a MOVING SPLITTER 
        //
        private int lastDrawSplit =1; 
        private int initialSplitterDistance; 
        private Rectangle initialSplitterRectangle;
        private Point anchor = Point.Empty; 
        private bool splitBegin = false;
        private bool splitMove = false;
        private bool splitBreak = false;
 
        //
        // Split Cursor 
        // 
        Cursor overrideCursor = null;
 
        //
        //Needed For Tabbing
        //
        Control nextActiveControl = null; 
        private bool callBaseVersion;
        private bool splitterFocused; 
 
        //
        //Required to keep track of Splitter movements.... 
        //
        private bool splitterClick;
        private bool splitterDrag;
 
        //
        // FixedPanel.None require us 
        // to keep the Width/Height Ratio Depending on SplitContainer.Orientation 
        //
 
        double ratioWidth = 0.0f;
        double ratioHeight = 0.0f;
        bool resizeCalled = false;
        bool splitContainerScaling = false; 
        bool setSplitterDistance = false;
 
        // 
        //Events
        // 
        private static readonly object EVENT_MOVING = new object();
        private static readonly object EVENT_MOVED = new object();

        // private IMessageFilter implementation 
        SplitContainerMessageFilter splitContainerMessageFilter = null;
 
 		//This would avoid re-entrant code into SelectNextControl. 
		private bool selectNextControl = false;
 
        //
        // Constructor
        //
        ///  
        public SplitContainer()
        { 
            // either the left or top panel - LTR 
            // either the right or top panel - RTL
            panel1 = new SplitterPanel(this); 
            // either the right or bottom panel - LTR
            // either the left or bottom panel - RTL
            panel2 = new SplitterPanel(this);
            splitterRect = new Rectangle(); 

            SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 

            ((WindowsFormsUtils.TypedControlCollection)this.Controls).AddInternal(panel1); 
            ((WindowsFormsUtils.TypedControlCollection)this.Controls).AddInternal(panel2);
            UpdateSplitter();

        } 

        ///////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                                         // 
        //PROPERTIES START IN ALPHABETICAL ORDER                                                   //
        //                                                                                         // 
        /////////////////////////////////////////////////////////////////////////////////////////////


 

        ///  
        ///  
        ///     This property is overridden to allow the AutoScroll to be set on all the panels when
        ///     The autoScroll on SplitContainer is shown. 
        ///     Here we dont set the base value ... but set autoscroll for panels.
        /// 
        [
        SRCategory(SR.CatLayout), 
        Localizable(true),
        DefaultValue(false), 
        SRDescription(SR.FormAutoScrollDescr), 
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never)
        ] 
        public override bool AutoScroll {
            get {
                //Always return false ... as Splitcontainer doesnt support AutoScroll
                return false; 
            }
 
            set { 
                base.AutoScroll = value;
            } 
        }

        [
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Never),
        DefaultValue(typeof(Point), "0, 0") 
        ] 
        public override Point AutoScrollOffset {
            get { 
               return base.AutoScrollOffset;
            }
            set {
                base.AutoScrollOffset = value; 
            }
        } 
 
        /// 
        ///  
        ///    Override AutoScrollMinSize to make it hidden from the user in the designer
        /// 
        [
        EditorBrowsable(EditorBrowsableState.Never), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        Browsable(false) 
        ] 
        public new Size AutoScrollMinSize {
            get { 
                return base.AutoScrollMinSize;
            }
            set {
                base.AutoScrollMinSize = value; 
            }
        } 
 

        ///  
        /// 
        ///    Override AutoScrollMargin to make it hidden from the user in the designer
        /// 
        [ 
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        Browsable(false) 
        ]
        public new Size AutoScrollMargin { 
            get {
                return base.AutoScrollMargin;
            }
            set { 
                base.AutoScrollMargin = value;
            } 
        } 

 
        [
        SRCategory(SR.CatLayout),
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.FormAutoScrollPositionDescr)
        ] 
        public new Point AutoScrollPosition { 
            get {
                return base.AutoScrollPosition; 
            }

            set {
                base.AutoScrollPosition = value; 
            }
        } 
 
        /// 
        ///     Hide AutoSize, as it can mean more than one thing and might confuse users 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override bool AutoSize 
        {
            get 
            { 
                return base.AutoSize;
            } 
            set
            {
                base.AutoSize = value;
            } 
        }
 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler AutoSizeChanged { 
            add {
                base.AutoSizeChanged += value;
            }
            remove { 
                base.AutoSizeChanged -= value;
            } 
        } 

 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        public override Image BackgroundImage { 
            get { 
                return base.BackgroundImage;
            } 
            set {
                base.BackgroundImage = value;
            }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override ImageLayout BackgroundImageLayout {
            get {
                return base.BackgroundImageLayout; 
            }
            set { 
                base.BackgroundImageLayout = value; 
            }
        } 


        /// 
        ///  
        /// 
        ///     
        ///       The binding manager for the container control. 
        ///    
        ///  
        [
        Browsable(false),
        SRDescription(SR.ContainerControlBindingContextDescr),
        SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly") 
        ]
        public override BindingContext BindingContext { 
            get { 
                return BindingContextInternal;
            } 
            set {
                BindingContextInternal = value;
            }
        } 

        ///  
        ///  
        ///     Indicates what type of border the Splitter control has.  This value
        ///     comes from the System.Windows.Forms.BorderStyle enumeration. 
        /// 
        [
        DefaultValue(BorderStyle.None),
        SRCategory(SR.CatAppearance), 
        System.Runtime.InteropServices.DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE),
        SRDescription(SR.SplitterBorderStyleDescr) 
        ] 
        public BorderStyle BorderStyle {
            get { 
                return borderStyle;
            }

            set { 
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)){ 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle)); 
                }
 
                if (borderStyle != value) {
                    borderStyle = value;
                    Invalidate();
                    SetInnerMostBorder(this); 
                    if (this.ParentInternal != null) {
                        if (this.ParentInternal is SplitterPanel) { 
                            SplitContainer sc = (SplitContainer)((SplitterPanel)this.ParentInternal).Owner; 
                            sc.SetInnerMostBorder(sc);
                        } 
                    }
                }

                switch (BorderStyle) 
                {
                    case BorderStyle.None: 
                        BORDERSIZE = 0; 
                        break;
                    case BorderStyle.FixedSingle: 
                        BORDERSIZE = 1;
                        break;
                    case BorderStyle.Fixed3D:
                        BORDERSIZE = 4; 
                        break;
                } 
            } 
        }
 
        /// 
        /// 
        ///     Controls Collection...
        ///     This is overriden so that the Controls.Add ( ) is not Code Gened... 
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public new Control.ControlCollection Controls {
            get { 
                return base.Controls;
            }
        }
 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event ControlEventHandler ControlAdded { 
            add {
                base.ControlAdded += value; 
            }
            remove {
                base.ControlAdded -= value;
            } 
        }
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event ControlEventHandler ControlRemoved {
             add { 
                 base.ControlRemoved += value;
             }
             remove {
                 base.ControlRemoved -= value; 
             }
        } 
        ///  
        /// 
        ///     The dock property. The dock property controls to which edge 
        ///     of the container this control is docked to. For example, when docked to
        ///     the top of the container, the control will be displayed flush at the
        ///     top of the container, extending the length of the container.
        ///  
        public new DockStyle Dock {
            get { 
                return base.Dock; 
            }
            set { 
                base.Dock = value;
                if (this.ParentInternal != null) {
                    if (this.ParentInternal is SplitterPanel) {
                        SplitContainer sc = (SplitContainer)((SplitterPanel)this.ParentInternal).Owner; 
                        sc.SetInnerMostBorder(sc);
                    } 
                } 
                ResizeSplitContainer();
            } 
        }

        /// 
        ///  
        ///     Deriving classes can override this to configure a default size for their control.
        ///     This is more efficient than setting the size in the control's constructor. 
        ///  
        protected override Size DefaultSize {
            get { 
                return new Size(150, 100);
            }
        }
 
        /// 
        ///  
        ///     Indicates what type of border the Splitter control has.  This value 
        ///     comes from the System.Windows.Forms.BorderStyle enumeration.
        ///  
        [
        DefaultValue(FixedPanel.None),
        SRCategory(SR.CatLayout),
        SRDescription(SR.SplitContainerFixedPanelDescr) 
        ]
        public FixedPanel FixedPanel { 
            get { 
                return fixedPanel;
            } 

            set {
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)FixedPanel.None, (int)FixedPanel.Panel2)){ 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(FixedPanel));
                } 
 
                if (fixedPanel != value) {
                    fixedPanel = value; 
                    // UpdatePanelSize !!
                    switch (fixedPanel) {
                        case FixedPanel.Panel2:
                            if (Orientation == Orientation.Vertical) { 
                                panelSize  = Width - SplitterDistanceInternal - SplitterWidthInternal;
                            } 
                            else { 
                                panelSize  = Height - SplitterDistanceInternal - SplitterWidthInternal;
                            } 
                            break;
                        default:
                            panelSize  =   SplitterDistanceInternal;
                            break; 
                    }
                } 
            } 
        }
 
        /// 
        /// 
        /// This property determines whether the the splitter can move.
        ///  
        [
        SRCategory(SR.CatLayout), 
        DefaultValue(false), 
        Localizable(true),
        SRDescription(SR.SplitContainerIsSplitterFixedDescr) 
        ]

        public bool IsSplitterFixed {
            get { 
                return splitterFixed;
            } 
            set { 
                splitterFixed = value;
            } 
        }

        //Private property used to check whether the splitter can be moved by the user.
        private bool IsSplitterMovable { 
            get {
                 if (Orientation == Orientation.Vertical) { 
                     return (Width >= Panel1MinSize + SplitterWidthInternal + Panel2MinSize); 
                 }
                 else { 
                     return (Height >= Panel1MinSize + SplitterWidthInternal + Panel2MinSize);
                 }

            } 
        }
 
        // VsWhidbey 434959 : Refer to IsContainerControl property on Control for more details. 
        internal override bool IsContainerControl
        { 
            get
            {
                return true;
            } 
        }
 
        ///  
        /// 
        /// This Property sets or gets if the splitter is vertical or horizontal. 
        /// 
        [
        SRCategory(SR.CatBehavior),
        DefaultValue(Orientation.Vertical), 
        Localizable(true),
        SRDescription(SR.SplitContainerOrientationDescr) 
        ] 
        public Orientation Orientation {
            get { return  orientation; } 
            set {
                //valid values are 0x0 to 0x1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)Orientation.Horizontal, (int)Orientation.Vertical)){
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(Orientation)); 
                }
                if (orientation != value) { 
                    orientation = value; 
					//update the splitterDistance to validate it w.r.t the new Orientation.
					splitDistance = 0; 
 					SplitterDistance = SplitterDistanceInternal;
                    UpdateSplitter();
                }
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        private Cursor OverrideCursor {
            get {
                return overrideCursor; 
            }
            set { 
                if (overrideCursor != value) { 
                    overrideCursor = value;
 
                    if (IsHandleCreated) {
                        // We want to instantly change the cursor if the mouse is within our bounds.
                        NativeMethods.POINT p = new NativeMethods.POINT();
                        NativeMethods.RECT r = new NativeMethods.RECT(); 
                        UnsafeNativeMethods.GetCursorPos(p);
                        UnsafeNativeMethods.GetWindowRect(new HandleRef(this, Handle), ref r); 
                        if ((r.left <= p.x && p.x < r.right && r.top <= p.y && p.y < r.bottom) || UnsafeNativeMethods.GetCapture() == Handle) 
                            SendMessage(NativeMethods.WM_SETCURSOR, Handle, NativeMethods.HTCLIENT);
                    } 
                }
            }
        }
 
        ///
        /// Indicates if either panel is collapsed 
        /// 
        private bool CollapsedMode {
            get { 
                return Panel1Collapsed || Panel2Collapsed;
            }
        }
 
        /// 
        ///  
        /// The Left or Top panel in the SplitContainer. 
        /// 
        [ 
        SRCategory(SR.CatAppearance),
        SRDescription(SR.SplitContainerPanel1Descr),
        Localizable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content) 
        ]
        public SplitterPanel Panel1 { 
            get { 
                return this.panel1;
            } 
        }

        ///
        ///     Collapses or restores the given panel 
        ///
        private void CollapsePanel(SplitterPanel p, bool collapsing) { 
            p.Collapsed = collapsing; 
            if (collapsing) {
                p.Visible = false; 

            }
            else {
                // restore panel 
                p.Visible = true;
            } 
            UpdateSplitter(); 
        }
 
        /// 
        /// 
        ///    
        ///    [To be supplied.] 
        ///    
        ///  
        [ 
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new Padding Padding {
            get { return base.Padding; } 
            set { base.Padding = value;}
        } 
 
        [
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        public new event EventHandler PaddingChanged {
            add { base.PaddingChanged += value; } 
            remove { base.PaddingChanged -= value; }
        } 
 
        /// 
        ///  
        /// Collapses or restores panel1
        /// 
        [
        SRCategory(SR.CatLayout), 
        DefaultValue(false),
        SRDescription(SR.SplitContainerPanel1CollapsedDescr) 
        ] 
        public bool Panel1Collapsed {
            get { 
                return panel1.Collapsed;
            }
            set {
                if (value != panel1.Collapsed) { 
                    if (value && panel2.Collapsed) {
                        CollapsePanel(panel2, false); 
                    } 
                    CollapsePanel(panel1, value);
                } 
            }
        }

 
        /// 
        ///  
        /// Collapses or restores panel2 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        DefaultValue(false),
        SRDescription(SR.SplitContainerPanel2CollapsedDescr)
        ] 
        public bool Panel2Collapsed {
            get { 
                return panel2.Collapsed; 
            }
            set { 
                if (value != panel2.Collapsed) {
                    if (value && panel1.Collapsed) {
                        CollapsePanel(panel1, false);
                    } 
                    CollapsePanel(panel2, value);
                } 
            } 
        }
 
        /// 
        /// 
        /// This property determines the minimum distance of pixels of the splitter from the left or the top edge of Panel1.
        ///  
        [
        SRCategory(SR.CatLayout), 
        DefaultValue(25), 
        Localizable(true),
        SRDescription(SR.SplitContainerPanel1MinSizeDescr), 
        RefreshProperties(RefreshProperties.All)
        ]
        public int Panel1MinSize {
            get { 
                return panel1MinSize;
            } 
            set { 
                if (value != Panel1MinSize)
                { 
                    if (value < 0)
                    {
                        throw new ArgumentOutOfRangeException("Panel1MinSize", SR.GetString(SR.InvalidLowBoundArgument, "Panel1MinSize", (value).ToString(CultureInfo.CurrentCulture), "0"));
                    } 

                    if (Orientation == Orientation.Vertical) { 
                       if (DesignMode && Width != DefaultSize.Width && value + Panel2MinSize + SplitterWidth > Width) 
                       {
                            throw new ArgumentOutOfRangeException("Panel1MinSize", SR.GetString(SR.InvalidArgument, "Panel1MinSize", (value).ToString(CultureInfo.CurrentCulture))); 
                       }

                    }
                    else if (Orientation == Orientation.Horizontal) { 
                        if (DesignMode && Height != DefaultSize.Height && value + Panel2MinSize + SplitterWidth > Height)
                        { 
                            throw new ArgumentOutOfRangeException("Panel1MinSize", SR.GetString(SR.InvalidArgument, "Panel1MinSize", (value).ToString(CultureInfo.CurrentCulture))); 
                        }
                    } 
                    panel1MinSize = value;
                    if (value > SplitterDistanceInternal) {
                        SplitterDistanceInternal = value;  //Set the Splitter Distance to the end of Panel1
                    } 
                }
            } 
        } 

        ///  
        /// 
        /// This is the Right or Bottom panel in the SplitContainer.
        /// 
        [ 
        SRCategory(SR.CatAppearance),
        SRDescription(SR.SplitContainerPanel2Descr), 
        Localizable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
        ] 
        public SplitterPanel Panel2 {
            get {
                return this.panel2;
            } 
        }
 
        ///  
        /// 
        /// This property determines the minimum distance of pixels of the splitter from the right or the bottom edge of Panel2 
        /// 
        [
        SRCategory(SR.CatLayout),
        DefaultValue(25), 
        Localizable(true),
        SRDescription(SR.SplitContainerPanel2MinSizeDescr), 
        RefreshProperties(RefreshProperties.All) 
        ]
        public int Panel2MinSize { 
            get {
                return panel2MinSize;
            }
            set { 
                if (value != Panel2MinSize)
                { 
                    if (value < 0) 
                    {
                        throw new ArgumentOutOfRangeException("Panel2MinSize", SR.GetString(SR.InvalidLowBoundArgument, "Panel2MinSize", (value).ToString(CultureInfo.CurrentCulture), "0")); 
                    }
                    if (Orientation == Orientation.Vertical) {
                        if (DesignMode && Width != DefaultSize.Width && value + Panel1MinSize + SplitterWidth > Width)
                        { 
                            throw new ArgumentOutOfRangeException("Panel2MinSize", SR.GetString(SR.InvalidArgument, "Panel2MinSize", (value).ToString(CultureInfo.CurrentCulture)));
                        } 
 
                    }
                    else if (Orientation == Orientation.Horizontal) { 
                        if (DesignMode && Height != DefaultSize.Height && value + Panel1MinSize + SplitterWidth > Height)
                        {
                            throw new ArgumentOutOfRangeException("Panel2MinSize", SR.GetString(SR.InvalidArgument, "Panel2MinSize", (value).ToString(CultureInfo.CurrentCulture)));
                        } 
                    }
                    panel2MinSize = value; 
                    if (value > Panel2.Width) { 
                        SplitterDistanceInternal = Panel2.Width + SplitterWidthInternal ;  //Set the Splitter Distance to the start of Panel2
                    } 
                }
            }
        }
 
        /// 
        ///  
        /// This property determines pixel distance of the splitter from the left or top edge. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        Localizable(true),
        SettingsBindable(true),
        SRDescription(SR.SplitContainerSplitterDistanceDescr), 
        DefaultValue(50)
        ] 
        public int SplitterDistance 
        {
            get 
            {
                return splitDistance;
            }
            set 
            {
                if (value != SplitterDistance) 
                { 
                    if (value < 0) {
                        throw new ArgumentOutOfRangeException("SplitterDistance", SR.GetString(SR.InvalidLowBoundArgument, "SplitterDistance", (value).ToString(CultureInfo.CurrentCulture), "0")); 
                    }


                    try 
                    {
                        setSplitterDistance = true; 
 
                        if (Orientation == Orientation.Vertical) {
 
                            if (value  < Panel1MinSize)
                            {
                                value = Panel1MinSize;
                            } 
                            if (value + SplitterWidthInternal > this.Width - Panel2MinSize)
                            { 
                                value = this.Width - Panel2MinSize - SplitterWidthInternal; 
                            }
                            if (value < 0 ) { 
                                throw new InvalidOperationException(SR.GetString(SR.SplitterDistanceNotAllowed));
                            }
                            splitDistance = value;
                            splitterDistance = value; 
                            panel1.WidthInternal = SplitterDistance;
 
                        } 
                        else {
 
                            if (value < Panel1MinSize)
                            {
                                value = Panel1MinSize;
                            } 

                            if (value + SplitterWidthInternal > this.Height - Panel2MinSize) 
                            { 
                                value = this.Height - Panel2MinSize - SplitterWidthInternal;
                            } 
                            if (value < 0 ) {
                                throw new InvalidOperationException(SR.GetString(SR.SplitterDistanceNotAllowed));
                            }
                            splitDistance = value; 
                            splitterDistance = value;
                            panel1.HeightInternal = SplitterDistance; 
                        } 

                        switch (fixedPanel) { 
                            case FixedPanel.Panel1:
                                panelSize  =   SplitterDistance;
                                break;
                            case FixedPanel.Panel2: 
                                if (Orientation == Orientation.Vertical) {
                                    panelSize  = Width - SplitterDistance - SplitterWidthInternal; 
                                } 
                                else {
                                    panelSize  = Height - SplitterDistance - SplitterWidthInternal; 
                                }
                                break;
                        }
                        UpdateSplitter(); 
                    }
                    finally 
                    { 
                        setSplitterDistance = false;
                    } 
                    OnSplitterMoved(new SplitterEventArgs(SplitterRectangle.X + SplitterRectangle.Width/2, SplitterRectangle.Y + SplitterRectangle.Height/2, SplitterRectangle.X, SplitterRectangle.Y));
                }
            }
        } 

        private int SplitterDistanceInternal { 
 
            get {
                return splitterDistance; 
            }
            set {
                SplitterDistance = value;
            } 
        }
 
        ///  
        /// 
        /// This determines the number of pixels the splitter moves in increments.This is defaulted to 1. 
        /// 
        [
        SRCategory(SR.CatLayout),
        DefaultValue(1), 
        Localizable(true),
        SRDescription(SR.SplitContainerSplitterIncrementDescr) 
        ] 
        public int SplitterIncrement {
            get { 
                return splitterInc;
            }
            set {
 
                if (value < 1 ) {
                    throw new ArgumentOutOfRangeException("SplitterIncrement", SR.GetString(SR.InvalidLowBoundArgumentEx, "SplitterIncrement", (value).ToString(CultureInfo.CurrentCulture), "1")); 
                } 

                splitterInc = value; 
            }
        }

 
        /// 
        ///  
        /// This property determines the rectangle bounds of the splitter. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        SRDescription(SR.SplitContainerSplitterRectangleDescr),
        Browsable(false)
        ] 
        public Rectangle SplitterRectangle {
            get { 
                Rectangle r = splitterRect; 
                r.X = splitterRect.X - Left;
                r.Y = splitterRect.Y - Top; 
                return r;
            }
        }
 
        /// 
        ///  
        /// This property determines the thickness of the splitter. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        SRDescription(SR.SplitContainerSplitterWidthDescr),
        Localizable(true),
        DefaultValue(4) 
        ]
        public int SplitterWidth { 
            get { 
                return splitterWidth;
            } 
            set {
                if (value != SplitterWidth)
                {
                    if (value < 1 ) { 
                        throw new ArgumentOutOfRangeException("SplitterWidth", SR.GetString(SR.InvalidLowBoundArgumentEx, "SplitterWidth", (value).ToString(CultureInfo.CurrentCulture), "1"));
                    } 
                    if (Orientation == Orientation.Vertical) { 
                       if (DesignMode && value + Panel1MinSize + Panel2MinSize > Width)
                       { 
                            throw new ArgumentOutOfRangeException("SplitterWidth", SR.GetString(SR.InvalidArgument, "SplitterWidth", (value).ToString(CultureInfo.CurrentCulture)));
                       }

                    } 
                    else if (Orientation == Orientation.Horizontal) {
                        if (DesignMode && value + Panel1MinSize + Panel2MinSize > Height) 
                        { 
                            throw new ArgumentOutOfRangeException("SplitterWidth", SR.GetString(SR.InvalidArgument, "SplitterWidth", (value).ToString(CultureInfo.CurrentCulture)));
                        } 
                    }
                    splitterWidth = value;
                    UpdateSplitter();
                } 
            }
        } 
 
        /// 
        ///    We need to have a internal Property for the SplitterWidth which returns zero if we are in collapased mode. 
        ///    This property is used to Layout SplitContainer.
        /// 
        private int SplitterWidthInternal {
            get { 
                // if CollapsedMode then splitterwidth == 0;
                return (CollapsedMode) ? 0 : splitterWidth; 
            } 
        }
 
        /// 
        /// 
        ///    Indicates whether the user can give the focus to this control using the TAB
        ///       key. This property is read-only. 
        /// 
        [ 
        SRCategory(SR.CatBehavior), 
        DefaultValue(true),
        DispId(NativeMethods.ActiveX.DISPID_TABSTOP), 
        SRDescription(SR.ControlTabStopDescr)
        ]
        public new bool TabStop {
            get { 
                return tabStop;
            } 
            set { 
                if (TabStop != value) {
                    tabStop = value; 
                    OnTabStopChanged(EventArgs.Empty);
                }
            }
        } 

        ///  
        ///  
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Bindable(false)] 
        public override string Text {
            get {
                return base.Text;
            } 
            set {
                base.Text = value; 
            } 
        }
 
        /////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                            //
        //END PROPERTIES                                                              //
        //                                                                            // 
        /////////////////////////////////////////////////////////////////////////////////////////////
 
 
        /////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                            // 
        //Start EVENT HANDLERS                                                        //
        //                                                                            //
        /////////////////////////////////////////////////////////////////////////////////////////////
 
        /// 
        ///  
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)] 
        new public event EventHandler BackgroundImageChanged {
            add { 
                base.BackgroundImageChanged += value;
            }
            remove {
                base.BackgroundImageChanged -= value; 
            }
        } 
 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackgroundImageLayoutChanged {
            add {
                base.BackgroundImageLayoutChanged += value; 
            }
            remove { 
                base.BackgroundImageLayoutChanged -= value; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [SRCategory(SR.CatBehavior), SRDescription(SR.SplitterSplitterMovingDescr)] 
        public event SplitterCancelEventHandler SplitterMoving { 
            add {
                Events.AddHandler(EVENT_MOVING, value); 
            }
            remove {
                Events.RemoveHandler(EVENT_MOVING, value);
            } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [SRCategory(SR.CatBehavior), SRDescription(SR.SplitterSplitterMovedDescr)]
        public event SplitterEventHandler SplitterMoved {
            add { 
                Events.AddHandler(EVENT_MOVED, value);
            } 
            remove { 
                Events.RemoveHandler(EVENT_MOVED, value);
            } 
        }

        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler TextChanged { 
            add { 
                base.TextChanged += value;
            } 
            remove {
                base.TextChanged -= value;
            }
        } 

        ///////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                            // 
        //End EVENT HANDLERS                                                          //
        //                                                                            // 
        /////////////////////////////////////////////////////////////////////////////////////////////


 
        /////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                            // 
        //start EVENT Delegates                                                       // 
        //                                                                            //
        ///////////////////////////////////////////////////////////////////////////////////////////// 

        /// 
        /// 
        ///     Overides the Control.OnGotFocus to Invalidate... 
        /// 
        protected override void OnGotFocus(EventArgs e) { 
            base.OnGotFocus(e); 
            Invalidate();
 
        }

        /// 
        ///  
        ///     Overrides the Control.OnKeydown for implementing splitter movements.
        ///  
        protected override void OnKeyDown(KeyEventArgs e) { 
            Debug.Assert(Enabled, "SplitContainer.OnKeyDown should not be called if the button is disabled");
            base.OnKeyDown(e); 
            //If the Panel1MinSize + Panel2MinSize < SplitContainer.Size then carry on the splitter move...
            if (IsSplitterMovable && !IsSplitterFixed) {
                if (e.KeyData == Keys.Escape && splitBegin) {
                    splitBegin = false; 
                    splitBreak = true;
                    return; 
                } 
                //valid Keys that move the splitter...
                if (e.KeyData == Keys.Right || e.KeyData == Keys.Down || 
                    e.KeyData == Keys.Left || e.KeyData == Keys.Up
                    && splitterFocused) {
                    if (splitBegin) {
                        splitMove = true; 
                    }
 
                    //left OR up 
                    if (e.KeyData == Keys.Left || e.KeyData == Keys.Up && splitterFocused) {
                        splitterDistance -= SplitterIncrement; 
                        splitterDistance = (splitterDistance < Panel1MinSize) ? splitterDistance + SplitterIncrement : Math.Max(splitterDistance, BORDERSIZE);
                    }
                    //right OR down
                    if (e.KeyData == Keys.Right || e.KeyData == Keys.Down && splitterFocused) { 
                        splitterDistance += SplitterIncrement;
                        if (Orientation == Orientation.Vertical) { 
                            splitterDistance = (splitterDistance + SplitterWidth > Width - Panel2MinSize -BORDERSIZE) ? splitterDistance - SplitterIncrement : splitterDistance; 
                        }
                        else { 
                            splitterDistance = (splitterDistance + SplitterWidth > Height - Panel2MinSize - BORDERSIZE) ? splitterDistance - SplitterIncrement : splitterDistance;
                        }

                    } 

                    if (!splitBegin) { 
                        splitBegin = true; 
                    }
                    //draw Helper start 
                    if (splitBegin && !splitMove) {
                        initialSplitterDistance = SplitterDistanceInternal;
                        DrawSplitBar(DRAW_START);
                    } 
                    else { //draw helper move
                        DrawSplitBar(DRAW_MOVE); 
                        //Moving by mouse .....gives the origin of the splitter.. 
                        //
                        Rectangle r = CalcSplitLine(splitterDistance, 0); 
                        int xSplit = r.X;
                        int ySplit = r.Y;
                        SplitterCancelEventArgs se = new SplitterCancelEventArgs(this.Left + SplitterRectangle.X + SplitterRectangle.Width/2, this.Top + SplitterRectangle.Y + SplitterRectangle.Height/2, xSplit, ySplit);
                        OnSplitterMoving(se); 
                        if (se.Cancel) {
                            SplitEnd(false); 
                        } 
                    }
                } //End Valid Keys.... 
            } //End SplitterFixed Check...
        }

        ///  
        /// 
        ///     Overrides the Control.OnKeydown for implementing splitter movements. 
        ///  
        protected override void OnKeyUp(KeyEventArgs e) {
            base.OnKeyUp(e); 
            if (splitBegin && IsSplitterMovable) {
                if (e.KeyData == Keys.Right || e.KeyData == Keys.Down ||
                    e.KeyData == Keys.Left || e.KeyData == Keys.Up
                    && splitterFocused) { 
                    DrawSplitBar(DRAW_END);
                    ApplySplitterDistance(); 
                    splitBegin = false; 
                    splitMove = false;
                } 
            }
            if (splitBreak) {
                splitBreak = false;
                SplitEnd(false); 
            }
            //problem with the Focus rect after Keyup .... 
            //Focus rect and reverible lines leave a trace behind on the splitter... 
            using (Graphics g = CreateGraphicsInternal()) {
                if (BackgroundImage == null) { 
                    g.FillRectangle(new SolidBrush(this.BackColor), SplitterRectangle);
                }
                DrawFocus(g, SplitterRectangle);
            } 

        } 
 
        /// 
        ///  
        ///     Overrides the Control.OnLayout.
        /// 
        protected override void OnLayout(LayoutEventArgs e) {
            SetInnerMostBorder(this); 

            if (IsSplitterMovable && !setSplitterDistance) { 
                ResizeSplitContainer(); 
            }
            base.OnLayout(e); 
        }

        /// 
        ///  
        ///     Overrides the Control.OnLostFocus to Invalidate.
        ///  
        protected override void OnLostFocus(EventArgs e) { 
            base.OnLostFocus(e);
            Invalidate(); 
        }

        /// 
        ///  
        /// Raises the  event.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override void OnMouseMove(MouseEventArgs e) {
            base.OnMouseMove(e); 
            if (!IsSplitterFixed && IsSplitterMovable) {

                //change cursor if default and user hasnt changed the cursor.
                if (Cursor == DefaultCursor && SplitterRectangle.Contains(e.Location)) 
                {
                    if (Orientation == Orientation.Vertical) { 
                        OverrideCursor = Cursors.VSplit; 
                    }
                    else { 
                        OverrideCursor = Cursors.HSplit;
                    }
                }
                else { 
                    OverrideCursor = null;;
                } 
 
                if (splitterClick) {
                    int x = e.X ; 
                    int y = e.Y ;
                    splitterDrag = true;
                    SplitMove(x, y);
                    if (Orientation == Orientation.Vertical) { 
                        x = Math.Max(Math.Min(x, Width - Panel2MinSize), Panel1MinSize);
                        y = Math.Max(y, 0); 
                    } 
                    else {
                        y = Math.Max(Math.Min(y, Height - Panel2MinSize), Panel1MinSize); 
                        x = Math.Max(x, 0);
                    }
                    Rectangle r = CalcSplitLine(GetSplitterDistance(e.X, e.Y), 0);
                    int xSplit = r.X; 
                    int ySplit = r.Y;
                    SplitterCancelEventArgs se = new SplitterCancelEventArgs(x, y, xSplit, ySplit); 
                    OnSplitterMoving(se); 
                    if (se.Cancel) {
                        SplitEnd(false); 

                    }
                }
            } 
        }
 
        ///  
        /// 
        /// Raises the  event. 
        /// 
        protected override void OnMouseLeave(EventArgs e) {
            base.OnMouseLeave(e);
            if (!Enabled) { 
                return;
            } 
            OverrideCursor = null; 
        }
 
        /// 
        /// 
        /// Raises the  event.
        ///  
        protected override void OnMouseDown(MouseEventArgs e) {
            base.OnMouseDown(e); 
            //If the Panel1MinSize + Panel2MinSize < SplitContainer.Size then carry on the splitter move... 
            if (IsSplitterMovable && SplitterRectangle.Contains(e.Location)) {
                if (!Enabled) { 
                    return;
                }
                if (e.Button == MouseButtons.Left && e.Clicks == 1 && !IsSplitterFixed) {
                    // Focus the current splitter OnMouseDown. 
                    splitterFocused = true;
                    IContainerControl c = this.ParentInternal.GetContainerControlInternal(); 
                    if (c != null) { 
                        ContainerControl cc = c as ContainerControl;
                        if (cc == null) { 
                            c.ActiveControl = this;
                        }
                        else {
                            cc.SetActiveControlInternal(this); 
                        }
                    } 
                    SetActiveControlInternal(null); 
                    nextActiveControl = panel2;
 
                    SplitBegin(e.X, e.Y);
                    splitterClick  = true;
                }
            } 
        }
 
        ///  
        /// 
        /// Raises the  event. 
        /// 
        protected override void OnMouseUp(MouseEventArgs e) {
            base.OnMouseUp(e);
            if (!Enabled) { 
                return;
            } 
            if (!IsSplitterFixed && IsSplitterMovable && splitterClick) { 
                CaptureInternal = false;
 
                if (splitterDrag) {
                    CalcSplitLine(GetSplitterDistance(e.X, e.Y), 0);
                    SplitEnd(true);
                } 
                else {
                    SplitEnd(false); 
 
                }
                splitterClick  = false; 
                splitterDrag = false;
            }
        }
 
	/// 
 	///     Overrides the Control.OnMove() to synchronize the 
 	///     splitterRect with the position of the SplitContainer. 
	/// 
 	protected override void OnMove(EventArgs e) 
	{
	    base.OnMove(e);
	    SetSplitterRect(this.Orientation == Orientation.Vertical);
 	} 
		
 
        ///  
        /// 
        ///     Overrides the Control.OnPaint() to focus the Splitter. 
        /// 
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
            if (Focused) { 
                DrawFocus(e.Graphics,SplitterRectangle);
            } 
        } 

        ///  
        /// 
        ///     Inherriting classes should override this method to respond to the
        ///     splitterMoving event. This event occurs while the splitter is
        ///     being moved by the user. 
        /// 
        public void OnSplitterMoving(SplitterCancelEventArgs e) { 
            SplitterCancelEventHandler handler = (SplitterCancelEventHandler)Events[EVENT_MOVING]; 
            if (handler != null) handler(this, e);
 
        }

        /// 
        ///  
        ///     Inherriting classes should override this method to respond to the
        ///     splitterMoved event. This event occurs when the user finishes 
        ///     moving the splitter. 
        /// 
        public void OnSplitterMoved(SplitterEventArgs e) { 
            SplitterEventHandler handler = (SplitterEventHandler)Events[EVENT_MOVED];
            if (handler != null) handler(this, e);
        }
 
        ////////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                                            // 
        ///END DELEGATES                                                                              // 
        //                                                                                            //
        //////////////////////////////////////////////////////////////////////////////////////////////// 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override void OnRightToLeftChanged(EventArgs e) { 
            base.OnRightToLeftChanged(e);
            // pass the RightToLeft value to the Parent. 
            this.panel1.RightToLeft = this.RightToLeft;
            this.panel2.RightToLeft = this.RightToLeft;
            UpdateSplitter();
        } 

 
        //////////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                                            //
        ///START PRIVATE FUNCTIONS                                                                    // 
        //                                                                                            //
        ////////////////////////////////////////////////////////////////////////////////////////////////

 
        /// 
        ///  
        ///     Sets the split position to be the current split size. This is called 
        ///     by splitEdit
        ///  
        /// 
        private void ApplySplitterDistance() {

            using (new System.Windows.Forms.Layout.LayoutTransaction(this, this, "SplitterDistance", false)) { 
                SplitterDistanceInternal = splitterDistance;
            } 
 
            // Refer to VsWhidbey : 467815: We need to invalidate when we have transparent backgournd.
            if (this.BackColor == Color.Transparent) { 
                // the panel1 retains the focus rect... so Invalidate the rect ...
                Invalidate();
            }
 
            if (Orientation == Orientation.Vertical) {
 
                if (RightToLeft == RightToLeft.No) { 
                    splitterRect.X = this.Location.X + SplitterDistanceInternal;
                } 
                else {
                    splitterRect.X = this.Right - SplitterDistanceInternal - SplitterWidthInternal;
                }
            } 
            else {
                splitterRect.Y = this.Location.Y + SplitterDistanceInternal; 
            } 
        }
 
        /// 
        /// 
        ///     Calculates the bounding rect of the split line. minWeight refers
        ///     to the minimum height or width of the splitline. 
        /// 
        private Rectangle CalcSplitLine(int splitSize, int minWeight) { 
 
           Rectangle r = new Rectangle();
            switch (Orientation) { 
                case Orientation.Vertical:
                    r.Width =  SplitterWidthInternal ;
                    r.Height = Height;
                    if (r.Width < minWeight) { 
                        r.Width = minWeight;
                    } 
 
                    if (RightToLeft == RightToLeft.No) {
                        r.X = panel1.Location.X + splitSize; 
                    }
                    else {
                        r.X = Width - splitSize - SplitterWidthInternal;
                    } 

                    break; 
 

                case Orientation.Horizontal: 
                    r.Width = Width;
                    r.Height = SplitterWidthInternal;
                    if (r.Width < minWeight) {
                        r.Width = minWeight; 
                    }
                    r.Y = panel1.Location.Y + splitSize; 
                    break; 
            }
            return r; 
        }

        /// 
        ///  
        ///     Draws the splitter bar at the current location. Will automatically
        ///     cleanup anyplace the splitter was drawn previously. 
        ///  
        /// 
        private void DrawSplitBar(int mode) { 
            if (mode != DRAW_START && lastDrawSplit != -1) {
                DrawSplitHelper(lastDrawSplit);
                lastDrawSplit = -1;
            } 
            // Bail if drawing with no old point...
            // 
            else if (mode != DRAW_START && lastDrawSplit == -1) { 
                return;
            } 

            if (mode != DRAW_END) {
                if (splitMove || splitBegin) { // Splitter is moved by keys and not by mouse
                        DrawSplitHelper(splitterDistance); 
                        lastDrawSplit = splitterDistance;
                } 
                else { 
                    DrawSplitHelper(splitterDistance);
                    lastDrawSplit = splitterDistance; 
                }

            }
            else { 
                if (lastDrawSplit != -1) {
                    DrawSplitHelper(lastDrawSplit); 
                } 
                lastDrawSplit = -1;
            } 
        }

        /// 
        ///     
        ///       Draws the focus rectangle if the control has focus.
        /// 
        ///     
        /// 
        private void DrawFocus(Graphics g, Rectangle r) { 
            r.Inflate (-1, -1);
            ControlPaint.DrawFocusRectangle(g, r, this.ForeColor, this.BackColor);
        }
 
        /// 
        ///  
        ///     Draws the splitter line at the requested location. Should only be called 
        ///     by drawSpltBar.
        ///  
        /// 
        private void DrawSplitHelper(int splitSize) {

            Rectangle r = CalcSplitLine(splitSize, 3); 
            IntPtr parentHandle = this.Handle;
            IntPtr dc = UnsafeNativeMethods.GetDCEx(new HandleRef(this, parentHandle), NativeMethods.NullHandleRef, NativeMethods.DCX_CACHE | NativeMethods.DCX_LOCKWINDOWUPDATE); 
            IntPtr halftone = ControlPaint.CreateHalftoneHBRUSH(); 
            IntPtr saveBrush = SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, halftone));
            SafeNativeMethods.PatBlt(new HandleRef(this, dc), r.X, r.Y, r.Width, r.Height, NativeMethods.PATINVERT); 
            SafeNativeMethods.SelectObject(new HandleRef(this, dc), new HandleRef(null, saveBrush));
            SafeNativeMethods.DeleteObject(new HandleRef(null, halftone));
            UnsafeNativeMethods.ReleaseDC(new HandleRef(this, parentHandle), new HandleRef(null, dc));
        } 

        ///  
        ///  
        ///     Calculates the split size based on the mouse position (x, y).
        ///  
        /// 
        private int GetSplitterDistance(int x, int y) {
            int delta;
            if (Orientation == Orientation.Vertical) { 
                delta = x - anchor.X;
            } 
            else { 
                delta = y - anchor.Y;
            } 

            // Negative delta - moving to the left
            // Positive delta - moving to the right
 
            int size = 0;
            switch (Orientation) { 
                case Orientation.Vertical: 
                    if (RightToLeft == RightToLeft.No) {
                        size = Math.Max(panel1.Width + delta, BORDERSIZE); 
                    }
                    else {
                        // In RTL negative delta actually means increasing the size....
                        size = Math.Max(panel1.Width - delta, BORDERSIZE); 
                    }
                    break; 
                case Orientation.Horizontal: 
                    size = Math.Max(panel1.Height + delta, BORDERSIZE);
                    break; 
            }
            if (Orientation == Orientation.Vertical) {
                return Math.Max(Math.Min(size, Width - Panel2MinSize), Panel1MinSize);
            } 
            else {
                return Math.Max(Math.Min(size, Height - Panel2MinSize), Panel1MinSize); 
            } 
        }
 
        /// 
        ///     Process an arrowKey press by selecting the next control in the group
        ///     that the activeControl belongs to.
        ///  
        /// 
        private bool ProcessArrowKey(bool forward) { 
            Control group = this; 
            if (ActiveControl != null) {
                group = ActiveControl.ParentInternal; 
            }
            return group.SelectNextControl(ActiveControl, forward, false, false, true);
        }
 
        /// 
        ///  
        ///     Re paint SplitterRect for SplitContainer 
        /// 
        ///  
        private void RepaintSplitterRect()
        {
            if (IsHandleCreated) {
                Graphics g = this.CreateGraphicsInternal(); 
                if (BackgroundImage != null) {
 
                    using (TextureBrush textureBrush = new TextureBrush(BackgroundImage,WrapMode.Tile)) { 
                        g.FillRectangle(textureBrush, ClientRectangle);
                    } 
                }
                else{
                    g.FillRectangle(new SolidBrush(this.BackColor), splitterRect);
                } 
                g.Dispose();
            } 
        } 

 
        private void SetSplitterRect(bool vertical) {
            if (vertical)
            {
                splitterRect.X = ((RightToLeft == RightToLeft.Yes) ? this.Width - splitterDistance - SplitterWidthInternal : this.Location.X + splitterDistance); 
                splitterRect.Y = this.Location.Y;
                splitterRect.Width = SplitterWidthInternal; 
                splitterRect.Height = this.Height; 
            }
            else 
            {
                splitterRect.X = this.Location.X;
                splitterRect.Y = this.Location.Y + SplitterDistanceInternal;
                splitterRect.Width = this.Width; 
                splitterRect.Height = SplitterWidthInternal;
            } 
        } 

        ///  
        /// 
        ///     Reize SplitContainer
        /// 
        ///  
        private void ResizeSplitContainer()
        { 
            if (splitContainerScaling) 
            {
                return; 
            }

            panel1.SuspendLayout();
            panel2.SuspendLayout(); 

            if (this.Width == 0) {         // Set the correct Width iif the WIDTH has changed to ZERO. 
                panel1.Size = new Size(0, panel1.Height); 
                panel2.Size = new Size(0, panel2.Height);
            } 
            else if (this.Height == 0) {   // Set the correct Height iif the HEIGHT has changed to ZERO.
                panel1.Size = new Size(panel1.Width, 0);
                panel2.Size = new Size(panel2.Width, 0);
            } 
            else
            { 
                if (Orientation == Orientation.Vertical) 
                {
                    // If no panel is collapsed then do the default ... 
                    if (!CollapsedMode)
                    {
                        if (this.FixedPanel == FixedPanel.Panel1) {
                            panel1.Size = new Size(panelSize, Height); 
                            panel2.Size = new Size(Math.Max(Width - panelSize - SplitterWidthInternal, Panel2MinSize), Height);
                        } 
                        if (this.FixedPanel == FixedPanel.Panel2) { 
                            panel2.Size = new Size(panelSize, Height);
                            splitterDistance = Math.Max(Width - panelSize - SplitterWidthInternal, Panel1MinSize); 
                            panel1.WidthInternal = splitterDistance;
                            panel1.HeightInternal = Height;
                        }
                        if (this.FixedPanel == FixedPanel.None) { 
                            if (ratioWidth != 0.0) {
                                splitterDistance = Math.Max((int)(Math.Floor(this.Width / ratioWidth)), Panel1MinSize); 
                            } 
                            panel1.WidthInternal = splitterDistance; //Default splitter distance from left or top.
                            panel1.HeightInternal = Height; 
                            panel2.Size = new Size(Math.Max(Width - splitterDistance - SplitterWidthInternal, Panel2MinSize), Height);
                        }
                        if (RightToLeft == RightToLeft.No) {
                            panel2.Location = new Point(panel1.WidthInternal + SplitterWidthInternal, 0); 
                        }
                        else { 
                            panel1.Location = new Point(Width - panel1.WidthInternal, 0); 
                        }
                        RepaintSplitterRect(); 
                        SetSplitterRect(true);
                    }
                    else
                    { 
                        if (Panel1Collapsed) {
                            panel2.Size = this.Size; 
                            panel2.Location = new Point(0,0); 
                        }
                        else if (Panel2Collapsed) { 
                            panel1.Size = this.Size;
                            panel1.Location = new Point(0,0);
                        }
                    } 

                } 
                else if (Orientation == Orientation.Horizontal) { 
                    // If no panel is collapsed then do the default ...
                    if (!CollapsedMode) 
                    {
                        if (this.FixedPanel == FixedPanel.Panel1) {

                            //Default splitter distance from left or top. 
                            panel1.Size = new Size(Width, panelSize);
                            int panel2Start = panelSize + SplitterWidthInternal; 
                            panel2.Size = new Size(Width, Math.Max(Height - panel2Start, Panel2MinSize)); 
                            panel2.Location = new Point(0,panel2Start);
                        } 
                        if (this.FixedPanel == FixedPanel.Panel2) {

                            panel2.Size = new Size(Width, panelSize);
                            splitterDistance = Math.Max(Height - Panel2.Height - SplitterWidthInternal, Panel1MinSize); 
                            panel1.HeightInternal = splitterDistance;
                            panel1.WidthInternal = Width; 
                            int panel2Start = splitterDistance + SplitterWidthInternal; 
                            panel2.Location = new Point(0, panel2Start);
                        } 
                        if (this.FixedPanel == FixedPanel.None) {
                            //NO PANEL FIXED !!
                            if (ratioHeight != 0.0)
                            { 
                                splitterDistance = Math.Max((int)(Math.Floor(this.Height / ratioHeight )), Panel1MinSize);
                            } 
                            panel1.HeightInternal = splitterDistance; //Default splitter distance from left or top. 
                            panel1.WidthInternal = Width;
                            int panel2Start = splitterDistance + SplitterWidthInternal; 
                            panel2.Size = new Size(Width,Math.Max(Height - panel2Start, Panel2MinSize));
                            panel2.Location = new Point(0,panel2Start);

 
                        }
                        RepaintSplitterRect(); 
                        SetSplitterRect(false); 
                    }
                    else 
                    {
                        if (Panel1Collapsed) {
                            panel2.Size = this.Size;
                            panel2.Location = new Point(0,0); 
                        }
                        else if (Panel2Collapsed) { 
                            panel1.Size = this.Size; 
                            panel1.Location = new Point(0,0);
                        } 
                    }
                }
                try {
                    resizeCalled = true; 
                    ApplySplitterDistance();
                } 
                finally { 
                    resizeCalled = false;
                } 
            }
            panel1.ResumeLayout();
            panel2.ResumeLayout();
        } 

 
        ///  
        ///     Scales an individual control's location, size, padding and margin.
        ///     If the control is top level, this will not scale the control's location. 
        ///     This does not scale children or the size of auto sized controls.  You can
        ///     omit scaling in any direction by changing BoundsSpecified.
        ///
        ///     After the control is scaled the RequiredScaling property is set to 
        ///     BoundsSpecified.None.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override void ScaleControl(SizeF factor, BoundsSpecified specified) {
            try 
            {
                splitContainerScaling = true;
                base.ScaleControl(factor, specified);
 
                float scale;
                if (orientation == Orientation.Vertical) { 
                    scale = factor.Width; 
                }
                else { 
                    scale = factor.Height;
                }
                SplitterWidth = (int)Math.Round((float)SplitterWidth * scale);
            } 
            finally
            { 
                splitContainerScaling = false; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        protected override void Select(bool directed, bool forward) { 
            // avoid re-entrant code. 
            // SelectNextControl can call back on us.. and we might end up infinitely recursing.
            if (selectNextControl) 
            {
                return;
            }
            // continue selection iff panels have controls or tabstop is true. 
            if ((this.Panel1.Controls.Count > 0 || this.Panel2.Controls.Count > 0) || tabStop) {
                SelectNextControlInContainer(this, forward, true, true, false); 
            } 
            else { //If this SplitContainer cannot be selected let the parent select the next in line
                Control parent = this.ParentInternal; 
                if (parent != null)
                {
                    try
                    { 
                    	selectNextControl = true;
                    	parent.SelectNextControl(this, forward, true, true, true); 
                    } 
                    finally
                    { 
                    	selectNextControl = false;
                    }
                }
            } 
        }
 
        ///  
        /// 
        ///     Selects the next control following ctl. 
        /// 
        private bool SelectNextControlInContainer(Control ctl, bool forward, bool tabStopOnly,
                                      bool nested, bool wrap) {
            if (!Contains(ctl) || !nested && ctl.ParentInternal != this) ctl = null; 
            Control start = ctl;
            SplitterPanel firstPanel = null; 
            do { 
                ctl = GetNextControl(ctl, forward);
 
                SplitterPanel panel = ctl as SplitterPanel;
                if (panel != null && panel.Visible) {
                    //We have crossed over to the second Panel...
                    if (firstPanel != null) { 
                        break;
                    } 
                    firstPanel = panel; 
                }
                if (!forward && firstPanel != null && ctl.ParentInternal != firstPanel) { 
                    //goback to start correct re-ordering ....
                    ctl = firstPanel;
                    break;
                } 
                if (ctl == null) {
                    break; 
                } 
                else {
                    if (ctl.CanSelect && ctl.TabStop) { 
                        if (ctl is SplitContainer)
                        {
                            ((SplitContainer)ctl).Select(forward, forward);
                        } 
                        else
                        { 
                            SelectNextActiveControl(ctl, forward, tabStopOnly, nested, wrap); 
                        }
                        return true; 
                    }
                }
            } while (ctl != null);
            if (ctl != null && this.TabStop) { 
                //we are on Splitter.....Focus it
                splitterFocused = true; 
                IContainerControl c = this.ParentInternal.GetContainerControlInternal(); 
                if (c != null) {
                    ContainerControl cc = c as ContainerControl; 
                    if (cc == null) {
                        c.ActiveControl = this;
                    }
                    else { 
                        IntSecurity.ModifyFocus.Demand();
                        cc.SetActiveControlInternal(this); 
                    } 
                }
                SetActiveControlInternal(null); 
                nextActiveControl = ctl;
                return true;
            }
            else 
            {
                // If the splitter cannot be selected select the next control in the splitter 
                bool selected = SelectNextControlInPanel(ctl, forward, tabStopOnly, nested, wrap); 
                if (!selected)
                { 
                    Control parent = this.ParentInternal;
                    if (parent != null)
                    {
                        try 
                        {
                            selectNextControl = true; 
                            parent.SelectNextControl(this, forward, true, true, true); 
                        }
                        finally 
                        {
                            selectNextControl = false;
                        }
                    } 
                }
            } 
            return false; 
        }
 
        /// 
        /// 
        ///     Selects the next control following ctl.
        ///  
        [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
        private bool SelectNextControlInPanel(Control ctl, bool forward, bool tabStopOnly, 
                                      bool nested, bool wrap) { 

            if (!Contains(ctl) || !nested && ctl.ParentInternal != this) ctl = null; 
            Control start = ctl;
            do {
                ctl = GetNextControl(ctl, forward);
                if (ctl == null || (ctl is SplitterPanel && ctl.Visible)) { 
                    break;
                } 
                else { 
                    if (ctl.CanSelect && (!tabStopOnly || ctl.TabStop)) {
                        if (ctl is SplitContainer) 
                        {
                            ((SplitContainer)ctl).Select(forward, forward);
                        }
                        else 
                        {
                            SelectNextActiveControl(ctl, forward, tabStopOnly, nested, wrap); 
                        } 
                        return true;
                    } 
                }
            } while (ctl != null);

            //If CTL == null .. we r out of the Current SplitContainer... 
            if (ctl == null || (ctl is SplitterPanel && !ctl.Visible)) {
                callBaseVersion = true; 
 
            }
            //IF the CTL == typeof(SpliterPanel) find the NEXT Control... so that we know 
            // we can focus the NEXT control within this SPLITCONTAINER....
            else
            {
                ctl = GetNextControl(ctl, forward); 
                if (forward) {
                    nextActiveControl = panel2; 
                } 
                else {
                    if (ctl == null || !(ctl.ParentInternal.Visible)) { 
                        callBaseVersion = true;
                    }
                    else
                        nextActiveControl = panel2; 
                }
            } 
            return false; 
        }
 
        // This will select the correct active control in the containerControl (if the passed in control is a containerControl)
        private static void SelectNextActiveControl(Control ctl, bool forward, bool tabStopOnly, bool nested, bool wrap)
        {
            ContainerControl container = ctl as ContainerControl; 
            if (container != null)
            { 
                bool correctParentActiveControl = true; 
                if (container.ParentInternal != null)
                { 
                    IContainerControl c = container.ParentInternal.GetContainerControlInternal();
                    if (c != null)
                    {
                        c.ActiveControl = container; 
                        correctParentActiveControl = (c.ActiveControl == container);
                    } 
                } 
                if (correctParentActiveControl)
                { 
                    ctl.SelectNextControl(null, forward, tabStopOnly, nested, wrap);
                }
            }
            else 
            {
                ctl.Select(); 
            } 
        }
 
        /// 
        /// 
        ///     Selects the innermost PANEL.
        ///  
        private void SetInnerMostBorder(SplitContainer sc) {
            foreach(Control ctl in sc.Controls) { 
                bool foundChildSplitContainer = false; 
                if (ctl is SplitterPanel) {
                    foreach (Control c in ctl.Controls) { 
                        SplitContainer c1 = c as SplitContainer;
                        if (c1 != null && c1.Dock == DockStyle.Fill) {
                           // We need to Overlay borders
                           // if the Children have matching BorderStyles ... 
                           if (c1.BorderStyle != BorderStyle) {
                               break; 
                           } 
                           ((SplitterPanel)ctl).BorderStyle = BorderStyle.None;
                           SetInnerMostBorder(c1); 
                           foundChildSplitContainer = true;
                        }
                    }
                    if (!foundChildSplitContainer) { 
                        ((SplitterPanel)ctl).BorderStyle = BorderStyle;
                    } 
                } 
            }
        } 


        /// 
        ///  
        ///     This protected override allows us to check is an unvalid value is set for Width and Height.
        ///     The SplitContainer would not throw on invalid Size (i.e Width and Height) settings, but would correct the error like Form 
        ///     Say, the Panel1MinSize == 150 , Panel2MinSize == 50 and SplitterWidth == 4 and the user tries 
        ///     to set SplitContainer.Width = 50 ... then this function would try to correct the value to 204.. instead of throwing.
        ///  
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {

            // If we are changing Height, check if its greater than minimun else ... make it equal to the minimum
            if ((specified & BoundsSpecified.Height) != BoundsSpecified.None && Orientation == Orientation.Horizontal) { 
                if (height < Panel1MinSize + SplitterWidthInternal + Panel2MinSize)
                { 
                    height = Panel1MinSize + SplitterWidthInternal + Panel2MinSize; 
                }
            } 

            // If we are changing Width, check if its greater than minimun else ... make it equal to the minimum
            if ((specified & BoundsSpecified.Width) != BoundsSpecified.None && Orientation == Orientation.Vertical) {
                if (width < Panel1MinSize + SplitterWidthInternal + Panel2MinSize) 
                {
                    width = Panel1MinSize + SplitterWidthInternal + Panel2MinSize; 
                } 
            }
 
            base.SetBoundsCore(x, y, width, height, specified);

            SetSplitterRect(this.Orientation == Orientation.Vertical);
        } 

        ///  
        ///  
        ///     Begins the splitter moving.
        ///  
        /// 
        private void SplitBegin(int x, int y) {
            anchor = new Point(x, y);
            splitterDistance = GetSplitterDistance(x, y); 
            initialSplitterDistance = splitterDistance;
            initialSplitterRectangle = SplitterRectangle; 
 
            // SECREVIEW : We need a message filter to capture the ESC key
            //           to cancel the split action. 
            //           The method PreFilterMessage is adorned with a LinkDemand.
            //           But this is not enough since this is a public unsealed class.
            //           We should have private implementation of the IMessageFilter
            //           So that we dont expose this to the classed deriving from this public class 
            //           Refer to VsWhidbey : 423553 for more information.
            IntSecurity.UnmanagedCode.Assert(); 
            try { 
                if (splitContainerMessageFilter == null)
                { 
                   splitContainerMessageFilter = new SplitContainerMessageFilter(this);
                }
                Application.AddMessageFilter(splitContainerMessageFilter);
            } 
            finally {
                CodeAccessPermission.RevertAssert(); 
            } 
            CaptureInternal = true;
            DrawSplitBar(DRAW_START); 
        }

        /// 
        ///  
        ///     The split movement.
        ///  
        ///  
        private void SplitMove(int x, int y) {
            int size = GetSplitterDistance(x, y); 
            int delta = size - initialSplitterDistance;
            int mod = delta % SplitterIncrement;
            if (splitterDistance != size) {
                if (Orientation == Orientation.Vertical) 
                {
                	if (size + SplitterWidthInternal <= this.Width - Panel2MinSize - BORDERSIZE) 
                	{ 
                		splitterDistance = size - mod;
                	} 
                }
                else
                {
                	if (size + SplitterWidthInternal <= this.Height - Panel2MinSize - BORDERSIZE) 
                	{
                		splitterDistance = size - mod; 
                	} 
                }
            } 
            DrawSplitBar(DRAW_MOVE);
        }

        ///  
        /// 
        ///     Finishes the split movement. 
        ///  
        /// 
        private void SplitEnd(bool accept) { 
            DrawSplitBar(DRAW_END);
            if (splitContainerMessageFilter != null)
            {
                Application.RemoveMessageFilter(splitContainerMessageFilter); 
                splitContainerMessageFilter = null;
            } 
 
            if (accept) {
                ApplySplitterDistance(); 

            }
            else if (splitterDistance != initialSplitterDistance) {
                splitterClick = false; 
                splitterDistance = SplitterDistanceInternal = initialSplitterDistance;
            } 
            anchor = Point.Empty; 

        } 

        /// 
        /// 
        ///     Update Splitter 
        /// 
        ///  
        private void UpdateSplitter() { 
            if (splitContainerScaling)
            { 
                return;
            }
            panel1.SuspendLayout();
            panel2.SuspendLayout(); 
            if (Orientation == Orientation.Vertical) {
                bool isRTL = RightToLeft == RightToLeft.Yes; 
 
                //NO PANEL FIXED !!
                if (!CollapsedMode) { 

                    panel1.HeightInternal = Height;
                    panel1.WidthInternal = splitterDistance; //Default splitter distance from left or top.
                    panel2.Size = new Size(Width - splitterDistance - SplitterWidthInternal, Height); 

                    if (!isRTL) { 
                        panel1.Location = new Point(0,0); 
                        panel2.Location = new Point(splitterDistance + SplitterWidthInternal, 0);
                    } 
                    else {
                        panel1.Location = new Point(Width - splitterDistance, 0);
                        panel2.Location = new Point(0, 0);
                    } 

                    RepaintSplitterRect(); 
                    SetSplitterRect(true /*Vertical*/); 
                    if (!resizeCalled) {
                        ratioWidth =  ((double)(this.Width) / (double)(panel1.Width) > 0) ? (double)(this.Width) / (double)(panel1.Width) : ratioWidth; 
                    }


                } 
                else {
                    if (Panel1Collapsed) { 
                        panel2.Size = this.Size; 
                        panel2.Location = new Point(0,0);
                    } 
                    else if (Panel2Collapsed) {
                        panel1.Size = this.Size;
                        panel1.Location = new Point(0,0);
                    } 
                    // Update Ratio when the splitContainer is in CollapsedMode.
                    if (!resizeCalled) 
                    { 
                    	ratioWidth = ((double)(this.Width) / (double)(splitterDistance) > 0) ? (double)(this.Width) / (double)(splitterDistance) : ratioWidth;
                    } 
                }
            }
            else {
                //NO PANEL FIXED !! 
                if (!CollapsedMode) {
                    panel1.Location = new Point(0,0); 
                    panel1.WidthInternal = Width; 

                    panel1.HeightInternal = SplitterDistanceInternal; //Default splitter distance from left or top. 
                    int panel2Start = splitterDistance + SplitterWidthInternal;
                    panel2.Size = new Size(Width, Height - panel2Start);
                    panel2.Location = new Point(0,panel2Start);
 
                    RepaintSplitterRect();
                    SetSplitterRect(false/*Horizontal*/); 
 
                    if (!resizeCalled) {
                        ratioHeight =  ((double)(this.Height) / (double)(panel1.Height) > 0) ? (double)(this.Height) / (double)(panel1.Height) : ratioHeight; 
                    }
                }
                else {
                    if (Panel1Collapsed) { 
                        panel2.Size = this.Size;
                        panel2.Location = new Point(0,0); 
                    } 
                    else if (Panel2Collapsed) {
                        panel1.Size = this.Size; 
                        panel1.Location = new Point(0,0);
                    }

                    // Update Ratio when the splitContainer is in CollapsedMode. 
                    if (!resizeCalled)
                    { 
                    	ratioHeight = ((double)(this.Height) / (double)(splitterDistance) > 0) ? (double)(this.Height) / (double)(splitterDistance) : ratioHeight; 
                    }
                } 
            }
            panel1.ResumeLayout();
            panel2.ResumeLayout();
         } 

        ///  
        ///  
        ///     Handles the WM_SETCURSOR message
        ///  
        /// 
        private void WmSetCursor(ref Message m) {

            // Accessing through the Handle property has side effects that break this 
            // logic. You must use InternalHandle.
            // 
            if (m.WParam == InternalHandle && ((int)m.LParam & 0x0000FFFF) == NativeMethods.HTCLIENT) { 
                if (OverrideCursor != null) {
                    Cursor.CurrentInternal = OverrideCursor; 
                }
                else {
                    Cursor.CurrentInternal = Cursor;
                } 
            }
            else { 
                DefWndProc(ref m); 
            }
 
        }

        ///////////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                                               // 
        // END PRIVATE FUNCTIONS ...                                                                     //
        //                                                                                               // 
        /////////////////////////////////////////////////////////////////////////////////////////////////// 

 


        ///////////////////////////////////////////////////////////////////////////////////////////////////
        //                                                                                               // 
        // Start PROTECTED OVERRIDE FUNCTIONS                                                            //
        //                                                                                               // 
        /////////////////////////////////////////////////////////////////////////////////////////////////// 

        internal override void AfterControlRemoved(Control control, Control oldParent) { 
            base.AfterControlRemoved(control, oldParent);
            if (control is SplitContainer && control.Dock == DockStyle.Fill)
            {
               SetInnerMostBorder(this); 
            }
 
        } 

        ///  
        /// 
        /// 
        ///    Processes a dialog key. Overrides Control.processDialogKey(). This
        ///    method implements handling of the TAB, LEFT, RIGHT, UP, and DOWN 
        ///    keys in dialogs.
        ///    The method performs no processing on keys that include the ALT or 
        ///    CONTROL modifiers. For the TAB key, the method selects the next control 
        ///    on the form. For the arrow keys,
        ///    !!! 
        /// 
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
        protected override bool ProcessDialogKey(Keys keyData) {
#if DEBUG 
            Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "ContainerControl.ProcessDialogKey [" + keyData.ToString() + "]");
#endif 
            if ((keyData & (Keys.Alt | Keys.Control)) == Keys.None) { 
                Keys keyCode = (Keys)keyData & Keys.KeyCode;
                switch (keyCode) { 
                    case Keys.Tab:
                        if (ProcessTabKey((keyData & Keys.Shift) == Keys.None)) return true;
                        break;
                    case Keys.Left: 
                    case Keys.Right:
                    case Keys.Up: 
                    case Keys.Down: 
                        if (!splitterFocused) {
                            if (ProcessArrowKey(keyCode == Keys.Right || 
                                            keyCode == Keys.Down)) return true;
                        }
                        else
                            return false; 
                        break;
 
                } 
            }
            return base.ProcessDialogKey(keyData); 
        }

        /// 
        /// ///  
        ///   This will process the TabKey for the SplitContainer. The Focus needs to Shift from controls to the Left of the Splitter
        ///   to the splitter and then to the controls on the right of the splitter. This override implements this Logic. 
        ///  
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
        protected override bool ProcessTabKey(bool forward) { 
            //Dont Focus the Splitter if TabStop == False or if the Splitter is Fixed !!
            if (!tabStop || IsSplitterFixed) {
                return base.ProcessTabKey(forward);
            } 

            if (nextActiveControl != null) { 
                SetActiveControlInternal(nextActiveControl); 
                nextActiveControl = null;
            } 

            if (SelectNextControlInPanel(ActiveControl, forward, true, true, true)) {
                nextActiveControl = null;
                splitterFocused = false; 
                return true;
            } 
            else { 
                if (callBaseVersion) {
                    callBaseVersion = false; 
                    return base.ProcessTabKey(forward);
                }
                else {
                    //We are om Splitter ...... 
                    splitterFocused = true;
                    IContainerControl c = this.ParentInternal.GetContainerControlInternal(); 
                    if (c != null) { 
                        ContainerControl cc = c as ContainerControl;
                        if (cc == null) { 
                            c.ActiveControl = this;
                        }
                        else {
                            cc.SetActiveControlInternal(this); 
                        }
                    } 
                    SetActiveControlInternal(null); 
                    return true;
                } 
            }
        }

        protected override void OnMouseCaptureChanged(EventArgs e) { 
            base.OnMouseCaptureChanged(e);
            if (splitContainerMessageFilter != null) 
            { 
                Application.RemoveMessageFilter(splitContainerMessageFilter);
                splitContainerMessageFilter = null; 
            }
        }

        ///  
        /// 
        ///  
        ///  
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message msg) { 
            switch (msg.Msg) {
                case NativeMethods.WM_SETCURSOR:
                    WmSetCursor(ref msg);
                    break; 
                case NativeMethods.WM_SETFOCUS:
                    splitterFocused = true; 
                    base.WndProc(ref msg); 
                    break;
                case NativeMethods.WM_KILLFOCUS: 
                    splitterFocused = false;
                    base.WndProc(ref msg);
                    break;
 
                default:
                    base.WndProc(ref msg); 
                    break; 
            }
        } 


        /// 
        ///  
        /// 
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        protected override Control.ControlCollection CreateControlsInstance() {
            return new SplitContainerTypedControlCollection(this, typeof(SplitterPanel), /*isReadOnly*/true); 
        }


        /////////////////////////////////////////////////////////////////////////////////////////////////// 
        //                                                                                 //
        // End   PROTECTED OVERRIDE FUNCTIONS                                              // 
        //                                                                                 // 
        ///////////////////////////////////////////////////////////////////////////////////////////////////
 

        private class SplitContainerMessageFilter : IMessageFilter
        {
            private SplitContainer owner = null; 

            public SplitContainerMessageFilter(SplitContainer splitContainer) 
            { 
                this.owner = splitContainer;
            } 

            /// 
            /// 
            ///  
            /// 
            [ 
            System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 
            ]
            bool IMessageFilter.PreFilterMessage(ref Message m) { 
                if (m.Msg >= NativeMethods.WM_KEYFIRST && m.Msg <= NativeMethods.WM_KEYLAST) {
                    if ((m.Msg == NativeMethods.WM_KEYDOWN && (int)m.WParam == (int)Keys.Escape)
                        || (m.Msg == NativeMethods.WM_SYSKEYDOWN)) {
                        //Notify that splitMOVE was reverted .. 
                        //this is used in ONKEYUP!!
                        owner.splitBegin = false; 
                        owner.SplitEnd(false); 
                        owner.splitterClick  = false;
                        owner.splitterDrag = false; 
                    }
                    return true;
                }
                return false; 
            }
        } 
 
         /// 
         /// This control collection only allows a specific type of control 
         /// into the controls collection.  It optionally supports readonlyness.
         /// 
         internal class SplitContainerTypedControlCollection : WindowsFormsUtils.TypedControlCollection {
            SplitContainer owner; 

            public SplitContainerTypedControlCollection(Control c, Type type, bool isReadOnly): base(c, type, isReadOnly) 
            { 
              this.owner = c as SplitContainer;
            } 

            public override void Remove(Control value) {
                if (value is SplitterPanel) {
                    if (!owner.DesignMode) { 
                        if (IsReadOnly) throw new NotSupportedException(SR.GetString(SR.ReadonlyControlsCollection));
                    } 
                } 
                base.Remove(value);
            } 

            internal override void SetChildIndexInternal(Control child, int newIndex)
            {
               if (child is SplitterPanel) { 
                   if (!owner.DesignMode) {
                       if (IsReadOnly) { 
                           throw new NotSupportedException(SR.GetString(SR.ReadonlyControlsCollection)); 
                       }
                   } 
                   else {
                       // just no-op it at DT.
                       return;
                   } 
               }
               base.SetChildIndexInternal(child, newIndex); 
            } 

        } 

    }
 }

// 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