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)
32 using System.Runtime.InteropServices;
33 using System.ComponentModel;
35 using System.Drawing.Drawing2D;
37 namespace System.Windows.Forms
39 [ComVisibleAttribute (true)]
40 [ClassInterfaceAttribute (ClassInterfaceType.AutoDispatch)]
41 [DefaultEvent ("SplitterMoved")]
42 [Docking (DockingBehavior.AutoDock)]
43 [Designer ("System.Windows.Forms.Design.SplitContainerDesigner, " + Consts.AssemblySystem_Design)]
44 public class SplitContainer : ContainerControl
49 #region Local Variables
50 private FixedPanel fixed_panel;
51 private Orientation orientation;
53 private int splitter_increment;
54 private Rectangle splitter_rectangle;
55 private Rectangle splitter_rectangle_moving;
56 private Rectangle splitter_rectangle_before_move;
57 private bool splitter_fixed;
58 private bool splitter_dragging;
59 private int splitter_prev_move;
60 private Cursor restore_cursor;
61 private double fixed_none_ratio;
63 private SplitterPanel panel1;
64 private bool panel1_collapsed;
65 private int panel1_min_size;
67 private SplitterPanel panel2;
68 private bool panel2_collapsed;
69 private int panel2_min_size;
73 static object SplitterMovedEvent = new object ();
74 static object SplitterMovingEvent = new object ();
77 [EditorBrowsable (EditorBrowsableState.Never)]
78 public new event EventHandler AutoSizeChanged {
79 add { base.AutoSizeChanged += value; }
80 remove { base.AutoSizeChanged -= value; }
84 [EditorBrowsable (EditorBrowsableState.Always)]
85 public new event EventHandler BackgroundImageChanged {
86 add { base.BackgroundImageChanged += value; }
87 remove { base.BackgroundImageChanged -= value; }
91 [EditorBrowsable (EditorBrowsableState.Never)]
92 public new event EventHandler BackgroundImageLayoutChanged {
93 add { base.BackgroundImageLayoutChanged += value; }
94 remove { base.BackgroundImageLayoutChanged -= value; }
98 [EditorBrowsable (EditorBrowsableState.Never)]
99 public new event ControlEventHandler ControlAdded {
100 add { base.ControlAdded += value; }
101 remove { base.ControlAdded -= value; }
105 [EditorBrowsable (EditorBrowsableState.Never)]
106 public new event ControlEventHandler ControlRemoved {
107 add { base.ControlRemoved += value; }
108 remove { base.ControlRemoved -= value; }
112 [EditorBrowsable (EditorBrowsableState.Never)]
113 public new event EventHandler PaddingChanged {
114 add { base.PaddingChanged += value; }
115 remove { base.PaddingChanged -= value; }
118 public event SplitterEventHandler SplitterMoved {
119 add { Events.AddHandler (SplitterMovedEvent, value); }
120 remove { Events.RemoveHandler (SplitterMovedEvent, value); }
123 public event SplitterCancelEventHandler SplitterMoving {
124 add { Events.AddHandler (SplitterMovingEvent, value); }
125 remove { Events.RemoveHandler (SplitterMovingEvent, value); }
129 [EditorBrowsable (EditorBrowsableState.Never)]
130 public new event EventHandler TextChanged {
131 add { base.TextChanged += value; }
132 remove { base.TextChanged -= value; }
136 #region UIA Framework Events
137 static object UIACanResizeChangedEvent = new object ();
139 internal event EventHandler UIACanResizeChanged {
140 add { Events.AddHandler (UIACanResizeChangedEvent, value); }
141 remove { Events.RemoveHandler (UIACanResizeChangedEvent, value); }
144 internal void OnUIACanResizeChanged (EventArgs e)
146 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;
336 // UIA Framework Event: CanResize Changed
337 OnUIACanResizeChanged (EventArgs.Empty);
346 [RefreshProperties (RefreshProperties.All)]
347 public int Panel1MinSize {
348 get { return this.panel1_min_size; }
350 this.panel1_min_size = value;
354 [Localizable (false)]
355 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
356 public SplitterPanel Panel2 { get { return this.panel2; } }
358 [DefaultValue (false)]
359 public bool Panel2Collapsed {
360 get { return this.panel2_collapsed; }
362 if (panel2_collapsed != value) {
363 this.panel2_collapsed = value;
364 panel2.Visible = !value;
366 // UIA Framework Event: CanResize Changed
367 OnUIACanResizeChanged (EventArgs.Empty);
376 [RefreshProperties (RefreshProperties.All)]
377 public int Panel2MinSize {
378 get { return this.panel2_min_size; }
379 set { this.panel2_min_size = value; }
382 // MSDN says the default is 40, MS's implementation defaults to 50.
385 [SettingsBindable (true)]
386 public int SplitterDistance {
388 if (orientation == Orientation.Vertical)
389 return this.splitter_rectangle.X;
391 return this.splitter_rectangle.Y;
395 throw new ArgumentOutOfRangeException ();
397 if (value < panel1_min_size)
398 value = panel1_min_size;
401 if (orientation == Orientation.Vertical) {
402 if (this.Width - (this.SplitterWidth + value) < panel2_min_size)
403 value = this.Width - (this.SplitterWidth + panel2_min_size);
404 if (splitter_rectangle.X != value) {
405 splitter_rectangle.X = value;
409 if (this.Height - (this.SplitterWidth + value) < panel2_min_size)
410 value = this.Height - (this.SplitterWidth + panel2_min_size);
411 if (splitter_rectangle.Y != value) {
412 splitter_rectangle.Y = value;
418 OnSplitterMoved (new SplitterEventArgs (Left, Top, splitter_rectangle.X, splitter_rectangle.Y));
425 [MonoTODO ("Stub, never called")]
426 public int SplitterIncrement {
427 get { return this.splitter_increment; }
428 set { this.splitter_increment = value; }
432 public Rectangle SplitterRectangle { get { return splitter_rectangle; } }
436 public int SplitterWidth {
438 if (orientation == Orientation.Vertical)
439 return this.splitter_rectangle.Width;
441 return this.splitter_rectangle.Height;
445 throw new ArgumentOutOfRangeException ();
447 if (orientation == Orientation.Vertical)
448 this.splitter_rectangle.Width = value;
450 this.splitter_rectangle.Height = value;
456 [DefaultValue (true)]
457 [MonoTODO ("Stub, never called")]
458 new public bool TabStop {
459 get { return false; }
464 [EditorBrowsable (EditorBrowsableState.Never)]
466 public override string Text {
467 get { return base.Text; }
468 set { base.Text = value; }
472 #region Protected Properties
473 protected override Size DefaultSize { get { return new Size (150, 100); } }
476 #region Public Methods
479 public void BeginInit ()
484 public void EndInit ()
489 public void OnSplitterMoved (SplitterEventArgs e)
491 SplitterEventHandler eh = (SplitterEventHandler)(Events [SplitterMovedEvent]);
496 public void OnSplitterMoving (SplitterCancelEventArgs e)
498 SplitterCancelEventHandler eh = (SplitterCancelEventHandler)(Events [SplitterMovingEvent]);
504 #region Protected Methods
505 [EditorBrowsable (EditorBrowsableState.Advanced)]
506 protected override ControlCollection CreateControlsInstance ()
508 return new SplitContainerTypedControlCollection (this);
511 protected override void OnGotFocus (EventArgs e)
516 protected override void OnKeyDown (KeyEventArgs e)
521 protected override void OnKeyUp (KeyEventArgs e)
526 protected override void OnLayout (LayoutEventArgs e)
532 protected override void OnLostFocus (EventArgs e)
534 base.OnLostFocus (e);
537 protected override void OnMouseCaptureChanged (EventArgs e)
539 base.OnMouseCaptureChanged (e);
542 protected override void OnMouseDown (MouseEventArgs e)
544 base.OnMouseDown (e);
545 if (!splitter_fixed && SplitterHitTest (e.Location)) {
546 splitter_dragging = true;
547 SplitterBeginMove (e.Location);
551 protected override void OnMouseLeave (EventArgs e)
553 base.OnMouseLeave (e);
554 SplitterRestoreCursor ();
557 [EditorBrowsable (EditorBrowsableState.Advanced)]
558 protected override void OnMouseMove (MouseEventArgs e)
560 base.OnMouseMove (e);
562 if (splitter_dragging)
563 SplitterMove (e.Location);
565 if (!splitter_fixed && SplitterHitTest (e.Location))
566 SplitterSetCursor (orientation);
570 protected override void OnMouseUp (MouseEventArgs e)
573 if (splitter_dragging) {
574 SplitterEndMove (e.Location, false);
575 SplitterRestoreCursor ();
576 splitter_dragging = false;
580 protected override void OnPaint (PaintEventArgs e)
585 [EditorBrowsable (EditorBrowsableState.Advanced)]
586 protected override void OnRightToLeftChanged (EventArgs e)
588 base.OnRightToLeftChanged (e);
591 protected override bool ProcessDialogKey (Keys keyData)
593 return base.ProcessDialogKey (keyData);
596 protected override bool ProcessTabKey (bool forward)
598 return base.ProcessTabKey (forward);
601 [EditorBrowsable (EditorBrowsableState.Advanced)]
602 protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
604 base.ScaleControl (factor, specified);
607 protected override void Select (bool directed, bool forward)
609 base.Select (directed, forward);
612 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
614 base.SetBoundsCore (x, y, width, height, specified);
617 protected override void WndProc (ref Message msg)
619 base.WndProc (ref msg);
623 #region Private Methods
625 private bool SplitterHitTest (Point location)
627 if (location.X >= splitter_rectangle.X &&
628 location.X <= splitter_rectangle.X + splitter_rectangle.Width &&
629 location.Y >= splitter_rectangle.Y &&
630 location.Y <= splitter_rectangle.Y + splitter_rectangle.Height) {
636 private void SplitterBeginMove (Point location)
638 splitter_prev_move = orientation == Orientation.Vertical ? location.X : location.Y;
639 splitter_rectangle_moving = splitter_rectangle;
640 splitter_rectangle_before_move = splitter_rectangle;
643 private void SplitterMove (Point location)
645 int currentMove = orientation == Orientation.Vertical ? location.X : location.Y;
646 int delta = currentMove - splitter_prev_move;
647 Rectangle prev_location = splitter_rectangle_moving;
650 if (orientation == Orientation.Vertical) {
651 int min = panel1_min_size;
652 int max = panel2.Location.X + (panel2.Width - this.panel2_min_size) - splitter_rectangle_moving.Width;
654 if (splitter_rectangle_moving.X + delta > min && splitter_rectangle_moving.X + delta < max) {
655 splitter_rectangle_moving.X += delta;
658 // Ensure that the splitter is set to minimum or maximum position,
659 // even if the mouse "skips".
661 if (splitter_rectangle_moving.X + delta <= min && splitter_rectangle_moving.X != min) {
662 splitter_rectangle_moving.X = min;
664 } else if (splitter_rectangle_moving.X + delta >= max && splitter_rectangle_moving.X != max) {
665 splitter_rectangle_moving.X = max;
669 } else if (orientation == Orientation.Horizontal) {
670 int min = panel1_min_size;
671 int max = panel2.Location.Y + (panel2.Height - this.panel2_min_size) - splitter_rectangle_moving.Height;
673 if (splitter_rectangle_moving.Y + delta > min && splitter_rectangle_moving.Y + delta < max) {
674 splitter_rectangle_moving.Y += delta;
677 // Ensure that the splitter is set to minimum or maximum position,
678 // even if the mouse "skips".
680 if (splitter_rectangle_moving.Y + delta <= min && splitter_rectangle_moving.Y != min) {
681 splitter_rectangle_moving.Y = min;
683 } else if (splitter_rectangle_moving.Y + delta >= max && splitter_rectangle_moving.Y != max) {
684 splitter_rectangle_moving.Y = max;
691 splitter_prev_move = currentMove;
692 OnSplitterMoving (new SplitterCancelEventArgs (location.X, location.Y,
693 splitter_rectangle.X, splitter_rectangle.Y));
694 XplatUI.DrawReversibleRectangle (this.Handle, prev_location, 1);
695 XplatUI.DrawReversibleRectangle (this.Handle, splitter_rectangle_moving, 1);
699 private void SplitterEndMove (Point location, bool cancel)
702 // Prevent updating the splitter distance if the user changes it in e.g. the
703 // DoubleClick handler, but no delta move has happened in our drag-handling.
704 // We don't compare to splitter_rectangle for exactly that reason here
705 // (if it gets changed externally) and compare to a cached value.
707 if (splitter_rectangle_before_move != splitter_rectangle_moving) {
708 splitter_rectangle = splitter_rectangle_moving;
712 SplitterEventArgs args = new SplitterEventArgs (location.X, location.Y,
713 splitter_rectangle.X, splitter_rectangle.Y);
714 OnSplitterMoved (args);
717 private void SplitterSetCursor (Orientation orientation)
719 if (restore_cursor == null)
720 restore_cursor = this.Cursor;
721 this.Cursor = orientation == Orientation.Vertical ? Cursors.VSplit : Cursors.HSplit;
724 private void SplitterRestoreCursor ()
726 if (restore_cursor != null) {
727 this.Cursor = restore_cursor;
728 restore_cursor = null;
732 private void UpdateSplitter ()
734 this.SuspendLayout ();
735 panel1.SuspendLayout ();
736 panel2.SuspendLayout ();
738 if (panel1_collapsed) {
739 panel2.Size = this.Size;
740 panel2.Location = new Point (0, 0);
741 } else if (panel2_collapsed) {
742 panel1.Size = this.Size;
743 panel1.Location = new Point (0, 0);
745 panel1.Location = new Point (0, 0);
746 if (orientation == Orientation.Vertical) {
747 splitter_rectangle.Y = 0;
748 panel1.InternalHeight = panel2.InternalHeight = this.Height;
749 panel1.InternalWidth = Math.Max (this.SplitterDistance, panel1_min_size);
750 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
751 panel2.InternalWidth = Math.Max (this.Width - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
752 fixed_none_ratio = (double) this.Width / (double)this.SplitterDistance;
753 } else if (orientation == Orientation.Horizontal) {
754 splitter_rectangle.X = 0;
755 panel1.InternalWidth = panel2.InternalWidth = this.Width;
756 panel1.InternalHeight = Math.Max (this.SplitterDistance, panel1_min_size);
757 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
758 panel2.InternalHeight = Math.Max (this.Height - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
759 fixed_none_ratio = (double) this.Height / (double)this.SplitterDistance;
762 panel1.ResumeLayout ();
763 panel2.ResumeLayout ();
764 this.ResumeLayout ();
767 private void UpdateLayout ()
769 panel1.SuspendLayout ();
770 panel2.SuspendLayout ();
772 if (panel1_collapsed) {
773 panel2.Size = this.Size;
774 panel2.Location = new Point (0, 0);
775 } else if (panel2_collapsed) {
776 panel1.Size = this.Size;
777 panel1.Location = new Point (0, 0);
779 panel1.Location = new Point (0, 0);
780 if (orientation == Orientation.Vertical) {
781 panel1.Location = new Point (0, 0);
782 panel1.InternalHeight = panel2.InternalHeight = this.Height;
783 splitter_rectangle.Height = this.Height;
785 if (fixed_panel == FixedPanel.None) {
786 splitter_rectangle.X = Math.Max ((int)Math.Floor (((double)this.Width) / fixed_none_ratio), panel1_min_size); //set distance
787 panel1.InternalWidth = this.SplitterDistance;
788 panel2.InternalWidth = this.Width - (this.SplitterWidth + this.SplitterDistance);
789 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
790 } else if (fixed_panel == FixedPanel.Panel1) {
791 panel1.InternalWidth = this.SplitterDistance;
792 panel2.InternalWidth = Math.Max (this.Width - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
793 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
794 } else if (fixed_panel == FixedPanel.Panel2) {
795 splitter_rectangle.X = Math.Max (this.Width - (this.SplitterWidth + panel2.Width), panel1_min_size); //set distance
796 panel1.InternalWidth = this.SplitterDistance;
797 panel2.Location = new Point (this.SplitterWidth + this.SplitterDistance, 0);
799 } else if (orientation == Orientation.Horizontal) {
800 panel1.Location = new Point (0, 0);
801 panel1.InternalWidth = panel2.InternalWidth = this.Width;
802 splitter_rectangle.Width = this.Width;
804 if (fixed_panel == FixedPanel.None) {
805 splitter_rectangle.Y = Math.Max ((int) Math.Floor ((double)this.Height / fixed_none_ratio), panel1_min_size); //set distance
806 panel1.InternalHeight = this.SplitterDistance;
807 panel2.InternalHeight = this.Height - (this.SplitterWidth + this.SplitterDistance);
808 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
809 } else if (fixed_panel == FixedPanel.Panel1) {
810 panel1.InternalHeight = this.SplitterDistance;
811 panel2.InternalHeight = Math.Max (this.Height - (this.SplitterWidth + this.SplitterDistance), panel2_min_size);
812 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
813 } else if (fixed_panel == FixedPanel.Panel2) {
814 splitter_rectangle.Y = Math.Max (this.Height - (this.SplitterWidth + panel2.Height), panel1_min_size); //set distance
815 panel1.InternalHeight = this.SplitterDistance;
816 panel2.Location = new Point (0, this.SplitterWidth + this.SplitterDistance);
821 panel1.ResumeLayout ();
822 panel2.ResumeLayout ();
827 #region Internal Classes
828 internal class SplitContainerTypedControlCollection : ControlCollection
830 public SplitContainerTypedControlCollection (Control owner) : base (owner)