4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2006 Jonathan Pobst
24 // Copyright (c) 2007 Ivan N. Zlatev
27 // Jonathan Pobst (monkey@jpobst.com)
28 // Ivan N. Zlatev (contact@i-nz.net)
33 using System.Runtime.InteropServices;
34 using System.ComponentModel;
36 using System.Drawing.Drawing2D;
38 namespace System.Windows.Forms
40 [ComVisibleAttribute (true)]
41 [ClassInterfaceAttribute (ClassInterfaceType.AutoDispatch)]
42 [DefaultEvent ("SplitterMoved")]
43 [Docking (DockingBehavior.AutoDock)]
44 [Designer ("System.Windows.Forms.Design.SplitContainerDesigner, " + Consts.AssemblySystem_Design)]
45 public class SplitContainer : ContainerControl
47 #region Local Variables
48 private FixedPanel fixed_panel;
49 private Orientation orientation;
51 private int splitter_increment;
52 private Rectangle splitter_rectangle;
53 private Rectangle splitter_rectangle_moving;
54 private Rectangle splitter_rectangle_before_move;
55 private bool splitter_fixed;
56 private bool splitter_dragging;
57 private int splitter_prev_move;
58 private Cursor restore_cursor;
59 private double fixed_none_ratio;
61 private SplitterPanel panel1;
62 private bool panel1_collapsed;
63 private int panel1_min_size;
65 private SplitterPanel panel2;
66 private bool panel2_collapsed;
67 private int panel2_min_size;
71 static object SplitterMovedEvent = new object ();
72 static object SplitterMovingEvent = new object ();
75 [EditorBrowsable (EditorBrowsableState.Never)]
76 public new event EventHandler AutoSizeChanged {
77 add { base.AutoSizeChanged += value; }
78 remove { base.AutoSizeChanged -= value; }
82 [EditorBrowsable (EditorBrowsableState.Always)]
83 public new event EventHandler BackgroundImageChanged {
84 add { base.BackgroundImageChanged += value; }
85 remove { base.BackgroundImageChanged -= value; }
89 [EditorBrowsable (EditorBrowsableState.Never)]
90 public new event EventHandler BackgroundImageLayoutChanged {
91 add { base.BackgroundImageLayoutChanged += value; }
92 remove { base.BackgroundImageLayoutChanged -= value; }
96 [EditorBrowsable (EditorBrowsableState.Never)]
97 public new event ControlEventHandler ControlAdded {
98 add { base.ControlAdded += value; }
99 remove { base.ControlAdded -= value; }
103 [EditorBrowsable (EditorBrowsableState.Never)]
104 public new event ControlEventHandler ControlRemoved {
105 add { base.ControlRemoved += value; }
106 remove { base.ControlRemoved -= value; }
110 [EditorBrowsable (EditorBrowsableState.Never)]
111 public new event EventHandler PaddingChanged {
112 add { base.PaddingChanged += value; }
113 remove { base.PaddingChanged -= value; }
116 public event SplitterEventHandler SplitterMoved {
117 add { Events.AddHandler (SplitterMovedEvent, value); }
118 remove { Events.RemoveHandler (SplitterMovedEvent, value); }
121 public event SplitterCancelEventHandler SplitterMoving {
122 add { Events.AddHandler (SplitterMovingEvent, value); }
123 remove { Events.RemoveHandler (SplitterMovingEvent, value); }
127 [EditorBrowsable (EditorBrowsableState.Never)]
128 public new event EventHandler TextChanged {
129 add { base.TextChanged += value; }
130 remove { base.TextChanged -= value; }
134 #region UIA Framework Events
136 static object UIACanResizeChangedEvent = new object ();
138 internal event EventHandler UIACanResizeChanged {
139 add { Events.AddHandler (UIACanResizeChangedEvent, value); }
140 remove { Events.RemoveHandler (UIACanResizeChangedEvent, value); }
143 internal void OnUIACanResizeChanged (EventArgs e)
145 EventHandler eh = (EventHandler) Events [UIACanResizeChangedEvent];
152 #region Public Constructors
153 public SplitContainer ()
155 SetStyle (ControlStyles.SupportsTransparentBackColor, true);
156 SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
158 fixed_panel = FixedPanel.None;
159 orientation = Orientation.Vertical;
161 splitter_rectangle = new Rectangle (50, 0, 4, this.Height);
162 splitter_increment = 1;
163 splitter_prev_move = -1;
164 restore_cursor = null;
166 splitter_fixed = false;
167 panel1_collapsed = false;
168 panel2_collapsed = false;
169 panel1_min_size = 25;
170 panel2_min_size = 25;
172 panel1 = new SplitterPanel (this);
173 panel2 = new SplitterPanel (this);
174 panel1.Size = new Size (50, 50);
177 this.Controls.Add (panel2);
178 this.Controls.Add (panel1);
182 #region Public Properties
184 [EditorBrowsable (EditorBrowsableState.Never)]
186 [DefaultValue (false)]
187 public override bool AutoScroll {
188 get { return base.AutoScroll; }
189 set { base.AutoScroll = value; }
193 [EditorBrowsable (EditorBrowsableState.Never)]
194 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
195 new public Size AutoScrollMargin {
196 get { return base.AutoScrollMargin; }
197 set { base.AutoScrollMargin = value; }
201 [EditorBrowsable (EditorBrowsableState.Never)]
202 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
203 new public Size AutoScrollMinSize {
204 get { return base.AutoScrollMinSize; }
205 set { base.AutoScrollMinSize = value; }
209 [DefaultValue ("{X=0,Y=0}")]
210 [EditorBrowsable (EditorBrowsableState.Never)]
211 public override Point AutoScrollOffset {
212 get { return base.AutoScrollOffset; }
213 set { base.AutoScrollOffset = value; }
217 [EditorBrowsable (EditorBrowsableState.Never)]
218 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
219 new public Point AutoScrollPosition {
220 get { return base.AutoScrollPosition; }
221 set { base.AutoScrollPosition = value; }
225 [EditorBrowsable (EditorBrowsableState.Never)]
226 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
227 public override bool AutoSize {
228 get { return base.AutoSize; }
229 set { base.AutoSize = value; }
233 [EditorBrowsable (EditorBrowsableState.Always)]
234 public override Image BackgroundImage {
235 get { return base.BackgroundImage; }
236 set { base.BackgroundImage = value; }
240 [EditorBrowsable (EditorBrowsableState.Never)]
241 public override ImageLayout BackgroundImageLayout {
242 get { return base.BackgroundImageLayout; }
243 set { base.BackgroundImageLayout = value; }
247 public override BindingContext BindingContext {
248 get { return base.BindingContext; }
249 set { base.BindingContext = value; }
252 // MSDN says default is Fixed3D, creating a new SplitContainer says otherwise.
253 [DefaultValue (BorderStyle.None)]
255 public BorderStyle BorderStyle {
256 get { return panel1.BorderStyle; }
258 if (!Enum.IsDefined (typeof (BorderStyle), value))
259 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for BorderStyle", value));
261 panel1.BorderStyle = value;
262 panel2.BorderStyle = value;
266 [EditorBrowsable (EditorBrowsableState.Never)]
267 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
268 new public ControlCollection Controls { get { return base.Controls; } }
270 new public DockStyle Dock {
271 get { return base.Dock; }
272 set { base.Dock = value; }
275 [DefaultValue (FixedPanel.None)]
276 public FixedPanel FixedPanel {
277 get { return this.fixed_panel; }
279 if (!Enum.IsDefined (typeof (FixedPanel), value))
280 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for FixedPanel", value));
282 this.fixed_panel = value;
287 [DefaultValue (false)]
288 public bool IsSplitterFixed {
289 get { return splitter_fixed; }
290 set { splitter_fixed = value; }
294 [DefaultValue (Orientation.Vertical)]
295 public Orientation Orientation {
296 get { return this.orientation; }
298 if (!Enum.IsDefined (typeof (Orientation), value))
299 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for Orientation", value));
301 if (this.orientation != value) {
302 if (value == Orientation.Vertical) {
303 splitter_rectangle.Width = splitter_rectangle.Height;
304 splitter_rectangle.X = splitter_rectangle.Y;
306 splitter_rectangle.Height = splitter_rectangle.Width;
307 splitter_rectangle.Y = splitter_rectangle.X;
310 this.orientation = value;
311 this.UpdateSplitter ();
317 [EditorBrowsable (EditorBrowsableState.Never)]
318 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
319 new public Padding Padding {
320 get { return base.Padding; }
321 set { base.Padding = value; }
324 [Localizable (false)]
325 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
326 public SplitterPanel Panel1 { get { return this.panel1; } }
328 [DefaultValue (false)]
329 public bool Panel1Collapsed {
330 get { return this.panel1_collapsed; }
332 if (panel1_collapsed != value) {
333 this.panel1_collapsed = value;
334 panel1.Visible = !value;
337 // UIA Framework Event: CanResize Changed
338 OnUIACanResizeChanged (EventArgs.Empty);
348 [RefreshProperties (RefreshProperties.All)]
349 public int Panel1MinSize {
350 get { return this.panel1_min_size; }
352 this.panel1_min_size = value;
356 [Localizable (false)]
357 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
358 public SplitterPanel Panel2 { get { return this.panel2; } }
360 [DefaultValue (false)]
361 public bool Panel2Collapsed {
362 get { return this.panel2_collapsed; }
364 if (panel2_collapsed != value) {
365 this.panel2_collapsed = value;
366 panel2.Visible = !value;
369 // UIA Framework Event: CanResize Changed
370 OnUIACanResizeChanged (EventArgs.Empty);
380 [RefreshProperties (RefreshProperties.All)]
381 public int Panel2MinSize {
382 get { return this.panel2_min_size; }
383 set { this.panel2_min_size = value; }
386 // MSDN says the default is 40, MS's implementation defaults to 50.
389 [SettingsBindable (true)]
390 public int SplitterDistance {
392 if (orientation == Orientation.Vertical)
393 return this.splitter_rectangle.X;
395 return this.splitter_rectangle.Y;
399 throw new ArgumentOutOfRangeException ();
401 if (value < panel1_min_size)
402 value = panel1_min_size;
405 if (orientation == Orientation.Vertical) {
406 if (this.Width - (this.SplitterWidth + value) < panel2_min_size)
407 value = this.Width - (this.SplitterWidth + panel2_min_size);
408 if (splitter_rectangle.X != value) {
409 splitter_rectangle.X = value;
413 if (this.Height - (this.SplitterWidth + value) < panel2_min_size)
414 value = this.Height - (this.SplitterWidth + panel2_min_size);
415 if (splitter_rectangle.Y != value) {
416 splitter_rectangle.Y = value;
422 OnSplitterMoved (new SplitterEventArgs (Left, Top, splitter_rectangle.X, splitter_rectangle.Y));
429 [MonoTODO ("Stub, never called")]
430 public int SplitterIncrement {
431 get { return this.splitter_increment; }
432 set { this.splitter_increment = value; }
436 public Rectangle SplitterRectangle { get { return splitter_rectangle; } }
440 public int SplitterWidth {
442 if (orientation == Orientation.Vertical)
443 return this.splitter_rectangle.Width;
445 return this.splitter_rectangle.Height;
449 throw new ArgumentOutOfRangeException ();
451 if (orientation == Orientation.Vertical)
452 this.splitter_rectangle.Width = value;
454 this.splitter_rectangle.Height = value;
460 [DefaultValue (true)]
461 [MonoTODO ("Stub, never called")]
462 new public bool TabStop {
463 get { return false; }
468 [EditorBrowsable (EditorBrowsableState.Never)]
470 public override string Text {
471 get { return base.Text; }
472 set { base.Text = value; }
476 #region Protected Properties
477 protected override Size DefaultSize { get { return new Size (150, 100); } }
480 #region Public Methods
481 public void OnSplitterMoved (SplitterEventArgs e)
483 SplitterEventHandler eh = (SplitterEventHandler)(Events [SplitterMovedEvent]);
488 public void OnSplitterMoving (SplitterCancelEventArgs e)
490 SplitterCancelEventHandler eh = (SplitterCancelEventHandler)(Events [SplitterMovingEvent]);
496 #region Protected Methods
497 [EditorBrowsable (EditorBrowsableState.Advanced)]
498 protected override ControlCollection CreateControlsInstance ()
500 return new SplitContainerTypedControlCollection (this);
503 protected override void OnGotFocus (EventArgs e)
508 protected override void OnKeyDown (KeyEventArgs e)
513 protected override void OnKeyUp (KeyEventArgs e)
518 protected override void OnLayout (LayoutEventArgs e)
524 protected override void OnLostFocus (EventArgs e)
526 base.OnLostFocus (e);
529 protected override void OnMouseCaptureChanged (EventArgs e)
531 base.OnMouseCaptureChanged (e);
534 protected override void OnMouseDown (MouseEventArgs e)
536 base.OnMouseDown (e);
537 if (!splitter_fixed && SplitterHitTest (e.Location)) {
538 splitter_dragging = true;
539 SplitterBeginMove (e.Location);
543 protected override void OnMouseLeave (EventArgs e)
545 base.OnMouseLeave (e);
546 SplitterRestoreCursor ();
549 [EditorBrowsable (EditorBrowsableState.Advanced)]
550 protected override void OnMouseMove (MouseEventArgs e)
552 base.OnMouseMove (e);
554 if (splitter_dragging)
555 SplitterMove (e.Location);
557 if (!splitter_fixed && SplitterHitTest (e.Location))
558 SplitterSetCursor (orientation);
562 protected override void OnMouseUp (MouseEventArgs e)
565 if (splitter_dragging) {
566 SplitterEndMove (e.Location, false);
567 SplitterRestoreCursor ();
568 splitter_dragging = false;
572 protected override void OnPaint (PaintEventArgs e)
577 [EditorBrowsable (EditorBrowsableState.Advanced)]
578 protected override void OnRightToLeftChanged (EventArgs e)
580 base.OnRightToLeftChanged (e);
583 protected override bool ProcessDialogKey (Keys keyData)
585 return base.ProcessDialogKey (keyData);
588 protected override bool ProcessTabKey (bool forward)
590 return base.ProcessTabKey (forward);
593 [EditorBrowsable (EditorBrowsableState.Advanced)]
594 protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
596 base.ScaleControl (factor, specified);
599 protected override void Select (bool directed, bool forward)
601 base.Select (directed, forward);
604 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
606 base.SetBoundsCore (x, y, width, height, specified);
609 protected override void WndProc (ref Message msg)
611 base.WndProc (ref msg);
615 #region Private Methods
617 private bool SplitterHitTest (Point location)
619 if (location.X >= splitter_rectangle.X &&
620 location.X <= splitter_rectangle.X + splitter_rectangle.Width &&
621 location.Y >= splitter_rectangle.Y &&
622 location.Y <= splitter_rectangle.Y + splitter_rectangle.Height) {
628 private void SplitterBeginMove (Point location)
630 splitter_prev_move = orientation == Orientation.Vertical ? location.X : location.Y;
631 splitter_rectangle_moving = splitter_rectangle;
632 splitter_rectangle_before_move = splitter_rectangle;
635 private void SplitterMove (Point location)
637 int currentMove = orientation == Orientation.Vertical ? location.X : location.Y;
638 int delta = currentMove - splitter_prev_move;
639 Rectangle prev_location = splitter_rectangle_moving;
642 if (orientation == Orientation.Vertical) {
643 int min = panel1_min_size;
644 int max = panel2.Location.X + (panel2.Width - this.panel2_min_size) - splitter_rectangle_moving.Width;
646 if (splitter_rectangle_moving.X + delta > min && splitter_rectangle_moving.X + delta < max) {
647 splitter_rectangle_moving.X += delta;
650 // Ensure that the splitter is set to minimum or maximum position,
651 // even if the mouse "skips".
653 if (splitter_rectangle_moving.X + delta <= min && splitter_rectangle_moving.X != min) {
654 splitter_rectangle_moving.X = min;
656 } else if (splitter_rectangle_moving.X + delta >= max && splitter_rectangle_moving.X != max) {
657 splitter_rectangle_moving.X = max;
661 } else if (orientation == Orientation.Horizontal) {
662 int min = panel1_min_size;
663 int max = panel2.Location.Y + (panel2.Height - this.panel2_min_size) - splitter_rectangle_moving.Height;
665 if (splitter_rectangle_moving.Y + delta > min && splitter_rectangle_moving.Y + delta < max) {
666 splitter_rectangle_moving.Y += delta;
669 // Ensure that the splitter is set to minimum or maximum position,
670 // even if the mouse "skips".
672 if (splitter_rectangle_moving.Y + delta <= min && splitter_rectangle_moving.Y != min) {
673 splitter_rectangle_moving.Y = min;
675 } else if (splitter_rectangle_moving.Y + delta >= max && splitter_rectangle_moving.Y != max) {
676 splitter_rectangle_moving.Y = max;
683 splitter_prev_move = currentMove;
684 OnSplitterMoving (new SplitterCancelEventArgs (location.X, location.Y,
685 splitter_rectangle.X, splitter_rectangle.Y));
686 XplatUI.DrawReversibleRectangle (this.Handle, prev_location, 1);
687 XplatUI.DrawReversibleRectangle (this.Handle, splitter_rectangle_moving, 1);
691 private void SplitterEndMove (Point location, bool cancel)
694 // Prevent updating the splitter distance if the user changes it in e.g. the
695 // DoubleClick handler, but no delta move has happened in our drag-handling.
696 // We don't compare to splitter_rectangle for exactly that reason here
697 // (if it gets changed externally) and compare to a cached value.
699 if (splitter_rectangle_before_move != splitter_rectangle_moving) {
700 splitter_rectangle = splitter_rectangle_moving;
704 SplitterEventArgs args = new SplitterEventArgs (location.X, location.Y,
705 splitter_rectangle.X, splitter_rectangle.Y);
706 OnSplitterMoved (args);
709 private void SplitterSetCursor (Orientation orientation)
711 if (restore_cursor == null)
712 restore_cursor = this.Cursor;
713 this.Cursor = orientation == Orientation.Vertical ? Cursors.VSplit : Cursors.HSplit;
716 private void SplitterRestoreCursor ()
718 if (restore_cursor != null) {
719 this.Cursor = restore_cursor;
720 restore_cursor = null;
724 private void UpdateSplitter ()
726 this.SuspendLayout ();
727 panel1.SuspendLayout ();
728 panel2.SuspendLayout ();
730 if (panel1_collapsed) {
731 panel2.Size = this.Size;
732 panel2.Location = new Point (0, 0);
733 } else if (panel2_collapsed) {
734 panel1.Size = this.Size;
735 panel1.Location = new Point (0, 0);
737 panel1.Location = new Point (0, 0);
738 if (orientation == Orientation.Vertical) {
739 splitter_rectangle.Y = 0;
740 panel1.InternalHeight = panel2.InternalHeight = this.Height;
741 panel1.InternalWidth = Math.Max (this.SplitterDistance, panel1_min_size);
742 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
743 panel2.InternalWidth = Math.Max (this.Width - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
744 fixed_none_ratio = (double) this.Width / (double)this.SplitterDistance;
745 } else if (orientation == Orientation.Horizontal) {
746 splitter_rectangle.X = 0;
747 panel1.InternalWidth = panel2.InternalWidth = this.Width;
748 panel1.InternalHeight = Math.Max (this.SplitterDistance, panel1_min_size);
749 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
750 panel2.InternalHeight = Math.Max (this.Height - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
751 fixed_none_ratio = (double) this.Height / (double)this.SplitterDistance;
754 panel1.ResumeLayout ();
755 panel2.ResumeLayout ();
756 this.ResumeLayout ();
759 private void UpdateLayout ()
761 panel1.SuspendLayout ();
762 panel2.SuspendLayout ();
764 if (panel1_collapsed) {
765 panel2.Size = this.Size;
766 panel2.Location = new Point (0, 0);
767 } else if (panel2_collapsed) {
768 panel1.Size = this.Size;
769 panel1.Location = new Point (0, 0);
771 panel1.Location = new Point (0, 0);
772 if (orientation == Orientation.Vertical) {
773 panel1.Location = new Point (0, 0);
774 panel1.InternalHeight = panel2.InternalHeight = this.Height;
775 splitter_rectangle.Height = this.Height;
777 if (fixed_panel == FixedPanel.None) {
778 splitter_rectangle.X = Math.Max ((int)Math.Floor (((double)this.Width) / fixed_none_ratio), panel1_min_size); //set distance
779 panel1.InternalWidth = this.SplitterDistance;
780 panel2.InternalWidth = this.Width - (this.SplitterWidth + this.SplitterDistance);
781 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
782 } else if (fixed_panel == FixedPanel.Panel1) {
783 panel1.InternalWidth = this.SplitterDistance;
784 panel2.InternalWidth = Math.Max (this.Width - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
785 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
786 } else if (fixed_panel == FixedPanel.Panel2) {
787 splitter_rectangle.X = Math.Max (this.Width - (this.SplitterWidth + panel2.Width), panel1_min_size); //set distance
788 panel1.InternalWidth = this.SplitterDistance;
789 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
791 } else if (orientation == Orientation.Horizontal) {
792 panel1.Location = new Point (0, 0);
793 panel1.InternalWidth = panel2.InternalWidth = this.Width;
794 splitter_rectangle.Width = this.Width;
796 if (fixed_panel == FixedPanel.None) {
797 splitter_rectangle.Y = Math.Max ((int) Math.Floor ((double)this.Height / fixed_none_ratio), panel1_min_size); //set distance
798 panel1.InternalHeight = this.SplitterDistance;
799 panel2.InternalHeight = this.Height - (this.SplitterWidth + this.SplitterDistance);
800 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
801 } else if (fixed_panel == FixedPanel.Panel1) {
802 panel1.InternalHeight = this.SplitterDistance;
803 panel2.InternalHeight = Math.Max (this.Height - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
804 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
805 } else if (fixed_panel == FixedPanel.Panel2) {
806 splitter_rectangle.Y = Math.Max (this.Height - (this.SplitterWidth + panel2.Height), panel1_min_size); //set distance
807 panel1.InternalHeight = this.SplitterDistance;
808 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
813 panel1.ResumeLayout ();
814 panel2.ResumeLayout ();
819 #region Internal Classes
820 internal class SplitContainerTypedControlCollection : ControlCollection
822 public SplitContainerTypedControlCollection (Control owner) : base (owner)