1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2005 Novell, Inc.
23 // Jackson Harper (jackson@ximian.com)
27 using System.Collections;
28 using System.ComponentModel;
29 using System.ComponentModel.Design;
33 namespace System.Windows.Forms {
34 [DefaultEvent("SelectedIndexChanged")]
35 [DefaultProperty("TabPages")]
36 [Designer("System.Windows.Forms.Design.TabControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
37 public class TabControl : Control {
39 private int selected_index = -1;
40 private TabAlignment alignment;
41 private TabAppearance appearance;
42 private TabDrawMode draw_mode;
43 private bool multiline;
44 private ImageList image_list;
45 private Size item_size = Size.Empty;
46 private Point padding;
47 private int row_count = 1;
48 private bool hottrack;
49 private TabPageCollection tab_pages;
50 private bool show_tool_tips;
51 private TabSizeMode size_mode;
52 private Rectangle display_rect;
53 private bool show_slider = false;
54 private ButtonState right_slider_state;
55 private ButtonState left_slider_state;
56 private int slider_pos = 0;
59 #region Public Constructors
62 tab_pages = new TabPageCollection (this);
63 SetStyle (ControlStyles.UserPaint, false);
64 padding = ThemeEngine.Current.TabControlDefaultPadding;
65 item_size = ThemeEngine.Current.TabControlDefaultItemSize;
67 MouseDown += new MouseEventHandler (MouseDownHandler);
68 MouseUp += new MouseEventHandler (MouseUpHandler);
69 SizeChanged += new EventHandler (SizeChangedHandler);
72 #endregion // Public Constructors
74 #region Public Instance Properties
75 [DefaultValue(TabAlignment.Top)]
77 [RefreshProperties(RefreshProperties.All)]
78 public TabAlignment Alignment {
79 get { return alignment; }
81 if (alignment == value)
84 if (alignment == TabAlignment.Left || alignment == TabAlignment.Right)
90 [DefaultValue(TabAppearance.Normal)]
92 public TabAppearance Appearance {
93 get { return appearance; }
95 if (appearance == value)
103 [EditorBrowsable(EditorBrowsableState.Never)]
104 public override Color BackColor {
105 get { return base.BackColor; }
106 set { /* nothing happens on set on MS */ }
110 [EditorBrowsable(EditorBrowsableState.Never)]
111 public override Image BackgroundImage {
112 get { return base.BackgroundImage; }
113 set { base.BackgroundImage = value; }
116 public override Rectangle DisplayRectangle {
118 return ThemeEngine.Current.GetTabControlDisplayRectangle (this);
122 [DefaultValue(TabDrawMode.Normal)]
123 public TabDrawMode DrawMode {
124 get { return draw_mode; }
126 if (draw_mode == value)
134 [EditorBrowsable(EditorBrowsableState.Never)]
135 public override Color ForeColor {
136 get { return base.ForeColor; }
137 set { base.ForeColor = value; }
140 [DefaultValue(false)]
141 public bool HotTrack {
142 get { return hottrack; }
144 if (hottrack == value)
152 public ImageList ImageList {
153 get { return image_list; }
154 set { image_list = value; }
158 public Size ItemSize {
163 if (value.Height < 0 || value.Width < 0)
164 throw new ArgumentException ("'" + value + "' is not a valid value for 'ItemSize'.");
170 [DefaultValue(false)]
171 public bool Multiline {
172 get { return multiline; }
174 if (multiline == value)
177 if (!multiline && alignment == TabAlignment.Left || alignment == TabAlignment.Right)
178 alignment = TabAlignment.Top;
184 public Point Padding {
185 get { return padding; }
187 if (value.X < 0 || value.Y < 0)
188 throw new ArgumentException ("'" + value + "' is not a valid value for 'Padding'.");
189 if (padding == value)
198 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
199 public int RowCount {
200 get { return row_count; }
205 public int SelectedIndex {
206 get { return selected_index; }
208 if (selected_index == value)
210 if (selected_index < -1) {
211 throw new ArgumentException ("'" + value + "' is not a valid value for 'value'. " +
212 "'value' must be greater than or equal to -1.");
217 Rectangle invalid = Rectangle.Empty;
218 bool refresh = false;
220 if (-1 != value && show_slider && value < slider_pos) {
225 int le = TabPages [value].TabBounds.Right;
226 int re = ThemeEngine.Current.GetTabControlLeftScrollRect (this).Left;
228 if (-1 != value && show_slider && le > re) {
231 while (ind > 0 && diff > 0) {
232 diff -= TabPages [ind++].Width;
234 slider_pos = ind - 1;
238 if (selected_index != -1) {
240 invalid = GetTabRect (selected_index);
241 Controls [selected_index].Visible = false;
243 selected_index = value;
245 OnSelectedIndexChanged (EventArgs.Empty);
247 TabPage selected = (TabPage) Controls [selected_index];
249 if (selected_index != -1) {
250 invalid = Rectangle.Union (invalid, GetTabRect (selected_index));
251 selected.Visible = true;
252 // selected.Focus ();
260 } else if (selected_index != -1 && selected.Row != BottomRow) {
261 DropRow (TabPages [selected_index].Row);
262 // calculating what to invalidate here seems to be slower then just
263 // refreshing the whole thing
268 // The lines are drawn on the edges of the tabs so the invalid area should
269 // needs to include the extra pixels of line width.
270 if (appearance == TabAppearance.Normal)
271 invalid.Inflate (6, 4);
272 Invalidate (invalid);
278 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
279 public TabPage SelectedTab {
281 if (selected_index == -1)
283 return tab_pages [selected_index];
286 int index = IndexForTabPage (value);
287 if (index == selected_index)
289 SelectedIndex = index;
293 [DefaultValue(false)]
295 public bool ShowToolTips {
296 get { return show_tool_tips; }
298 if (show_tool_tips == value)
300 show_tool_tips = value;
305 [DefaultValue(TabSizeMode.Normal)]
306 [RefreshProperties(RefreshProperties.Repaint)]
307 public TabSizeMode SizeMode {
308 get { return size_mode; }
310 if (size_mode == value)
318 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
319 public int TabCount {
321 return tab_pages.Count;
326 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
327 [MergableProperty(false)]
328 public TabPageCollection TabPages {
329 get { return tab_pages; }
334 [EditorBrowsable(EditorBrowsableState.Never)]
335 public override string Text {
336 get { return base.Text; }
337 set { base.Text = value; }
340 #endregion // Public Instance Properties
342 #region Internal Properties
343 internal bool ShowSlider {
344 get { return show_slider; }
345 set { show_slider = value; }
348 internal int SliderPos {
349 get { return slider_pos; }
352 internal ButtonState RightSliderState {
353 get { return right_slider_state; }
356 internal ButtonState LeftSliderState {
357 get { return left_slider_state; }
360 private Size DefaultItemSize {
362 return ThemeEngine.Current.TabControlDefaultItemSize;
366 #endregion // Internal Properties
368 #region Protected Instance Properties
369 protected override CreateParams CreateParams {
371 CreateParams c = base.CreateParams;
376 protected override Size DefaultSize {
377 get { return new Size (200, 100); }
380 #endregion // Protected Instance Properties
382 #region Public Instance Methods
383 public Rectangle GetTabRect (int index)
385 TabPage page = GetTab (index);
386 return page.TabBounds;
389 public Control GetControl (int index)
391 return GetTab (index);
394 public override string ToString ()
396 string res = String.Concat (base.ToString (),
397 ", TabPages.Count: ",
400 res = String.Concat (res, ", TabPages[0]: ",
405 #endregion // Public Instance Methods
407 #region Protected Instance Methods
408 protected override Control.ControlCollection CreateControlsInstance ()
410 return new TabControl.ControlCollection (this);
413 protected override void CreateHandle ()
415 base.CreateHandle ();
419 protected override void OnHandleCreated (EventArgs e)
421 base.OnHandleCreated (e);
424 protected override void OnHandleDestroyed (EventArgs e)
426 base.OnHandleDestroyed (e);
429 protected override void OnFontChanged (EventArgs e)
431 base.OnFontChanged (e);
435 protected override void OnResize (EventArgs e)
440 protected override void OnStyleChanged (EventArgs e)
442 base.OnStyleChanged (e);
445 protected override bool ProcessKeyPreview (ref Message m)
447 if (ProcessKeyEventArgs (ref m))
449 return base.ProcessKeyPreview (ref m);
452 protected override void OnKeyDown (KeyEventArgs e)
454 if (e.KeyCode == Keys.Tab && (e.KeyData & Keys.Control) != 0) {
455 if ((e.KeyData & Keys.Shift) == 0)
456 SelectedIndex = (SelectedIndex + 1) % (TabCount);
458 SelectedIndex = (SelectedIndex - 1) % (TabCount);
460 } else if (e.KeyCode == Keys.Home) {
463 } else if (e.KeyCode == Keys.End) {
464 SelectedIndex = TabCount - 1;
466 } else if (e.KeyCode == Keys.Left && SelectedIndex > 0) {
469 } else if (e.KeyCode == Keys.Right && SelectedIndex < TabCount - 1) {
477 protected override bool IsInputKey (Keys key)
479 switch (key & Keys.KeyCode) {
484 return base.IsInputKey (key);
487 protected override void Dispose (bool disposing)
489 base.Dispose (disposing);
492 protected void RemoveAll ()
497 protected virtual object [] GetItems ()
499 TabPage [] pages = new TabPage [Controls.Count];
500 Controls.CopyTo (pages, 0);
504 protected virtual object [] GetItems (Type type)
506 object [] pages = (object []) Array.CreateInstance (type, Controls.Count);
507 Controls.CopyTo (pages, 0);
511 protected string GetToolTipText (object item)
513 TabPage page = (TabPage) item;
514 return page.ToolTipText;
517 protected override void WndProc (ref Message m)
519 switch ((Msg) m.Msg) {
521 PaintEventArgs paint_event;
522 paint_event = XplatUI.PaintEventStart (Handle, true);
523 PaintInternal (paint_event);
524 XplatUI.PaintEventEnd (Handle, true);
527 base.WndProc (ref m);
532 protected virtual void OnSelectedIndexChanged (EventArgs e)
534 if (SelectedIndexChanged != null)
535 SelectedIndexChanged (this, e);
538 #endregion // Protected Instance Methods
540 #region Internal & Private Methods
541 private bool CanScrollRight {
543 return (slider_pos < TabCount - 1);
547 private bool CanScrollLeft {
548 get { return slider_pos > 0; }
551 private void MouseDownHandler (object sender, MouseEventArgs e)
554 Rectangle right = ThemeEngine.Current.GetTabControlRightScrollRect (this);
555 Rectangle left = ThemeEngine.Current.GetTabControlLeftScrollRect (this);
556 if (right.Contains (e.X, e.Y)) {
557 right_slider_state = ButtonState.Pushed;
558 if (CanScrollRight) {
562 Invalidate (new Rectangle (0, 0, Width, DisplayRectangle.Top));
567 } else if (left.Contains (e.X, e.Y)) {
568 left_slider_state = ButtonState.Pushed;
573 Invalidate (new Rectangle (0, 0, Width, DisplayRectangle.Top));
581 int count = Controls.Count;
582 for (int i = SliderPos; i < count; i++) {
583 if (!GetTabRect (i).Contains (e.X, e.Y))
590 private void MouseUpHandler (object sender, MouseEventArgs e)
592 if (ShowSlider && (left_slider_state == ButtonState.Pushed || right_slider_state == ButtonState.Pushed)) {
594 if (left_slider_state == ButtonState.Pushed)
595 invalid = ThemeEngine.Current.GetTabControlLeftScrollRect (this);
597 invalid = ThemeEngine.Current.GetTabControlRightScrollRect (this);
598 left_slider_state = ButtonState.Normal;
599 right_slider_state = ButtonState.Normal;
601 Invalidate (invalid);
605 private void SizeChangedHandler (object sender, EventArgs e)
610 internal void UpdateTabpage (TabPage page)
615 internal int IndexForTabPage (TabPage page)
617 for (int i = 0; i < tab_pages.Count; i++) {
618 if (page == tab_pages [i])
624 private void ResizeTabPages ()
628 Rectangle r = DisplayRectangle;
629 foreach (TabPage page in Controls) {
634 private int MinimumTabWidth {
636 return ThemeEngine.Current.TabControlMinimumTabWidth;
640 private Size TabSpacing {
642 return ThemeEngine.Current.TabControlGetSpacing (this);
646 private void CalcTabRows ()
649 case TabAlignment.Right:
650 case TabAlignment.Left:
651 CalcTabRows (Height);
659 private void CalcTabRows (int row_width)
662 Size spacing = TabSpacing;
667 for (int i = 0; i < TabPages.Count; i++) {
668 TabPage page = TabPages [i];
673 if (SizeMode == TabSizeMode.Fixed) {
674 width = item_size.Width;
676 width = (int) DeviceContext.MeasureString (page.Text, Font).Width + (Padding.X * 2);
679 if (i == SelectedIndex)
681 if (width < MinimumTabWidth)
682 width = MinimumTabWidth;
684 if (xpos + width > row_width && multiline) {
686 for (int j = 0; j < i; j++) {
690 } else if (xpos + width > row_width) {
694 xpos += width + 1 + spacing.Width;
697 if (SelectedIndex != -1 && TabPages [SelectedIndex].Row != BottomRow)
698 DropRow (TabPages [SelectedIndex].Row);
701 private int BottomRow {
704 case TabAlignment.Right:
705 case TabAlignment.Bottom:
713 private int Direction
717 case TabAlignment.Right:
718 case TabAlignment.Bottom:
726 private void DropRow (int row)
728 int bottom = BottomRow;
729 int direction = Direction;
731 foreach (TabPage page in TabPages) {
732 if (page.Row == row) {
734 } else if (direction == 1 && page.Row < row) {
735 page.Row += direction;
736 } else if (direction == -1 && page.Row > row) {
737 page.Row += direction;
742 private int CalcYPos ()
744 if (Alignment == TabAlignment.Bottom) {
745 Rectangle r = ThemeEngine.Current.GetTabControlDisplayRectangle (this);
751 private int CalcXPos ()
753 if (Alignment == TabAlignment.Right) {
754 Rectangle r = ThemeEngine.Current.GetTabControlDisplayRectangle (this);
761 private void SizeTabs ()
764 case TabAlignment.Right:
765 case TabAlignment.Left:
774 private void SizeTabsV (int row_width)
778 Size spacing = TabSpacing;
779 int xpos = CalcXPos ();
782 if (TabPages.Count == 0)
785 prev_row = TabPages [0].Row;
787 for (int i = 0; i < TabPages.Count; i++) {
788 TabPage page = TabPages [i];
791 if (SizeMode == TabSizeMode.Fixed) {
792 width = item_size.Width;
794 width = (int) DeviceContext.MeasureString (page.Text, Font).Width + (Padding.X * 2);
797 if (width < MinimumTabWidth)
798 width = MinimumTabWidth;
799 if (page.Row != prev_row)
802 page.TabBounds = new Rectangle (xpos + (row_count - page.Row) * ((item_size.Height - 2) + spacing.Width),
803 ypos, item_size.Height - 2, width);
805 if (page.Row != prev_row) {
806 if (SizeMode == TabSizeMode.FillToRight && !ShowSlider) {
807 FillRowV (begin_prev, i - 1, ((row_width - TabPages [i - 1].TabBounds.Bottom) / (i - begin_prev)), spacing);
812 ypos += width + spacing.Width;
816 if (SizeMode == TabSizeMode.FillToRight && !ShowSlider) {
817 FillRowV (begin_prev, TabPages.Count - 1,
818 ((row_width - TabPages [TabPages.Count - 1].TabBounds.Bottom) / (TabPages.Count - begin_prev)), spacing);
821 if (SelectedIndex != -1) {
822 ExpandSelected (TabPages [SelectedIndex], 2, row_width - 1);
826 private void SizeTabs (int row_width)
828 int ypos = CalcYPos ();
830 Size spacing = TabSpacing;
834 if (TabPages.Count == 0)
837 prev_row = TabPages [0].Row;
839 // Reset the slider position if the slider isn't needed
840 // anymore (ie window size was increased so all tabs are visible)
844 for (int i = slider_pos; i < TabPages.Count; i++) {
845 TabPage page = TabPages [i];
848 if (SizeMode == TabSizeMode.Fixed) {
849 width = item_size.Width;
851 width = (int) DeviceContext.MeasureString (page.Text, Font).Width + (Padding.X * 2);
854 if (width < MinimumTabWidth)
855 width = MinimumTabWidth;
856 if (page.Row != prev_row)
859 page.TabBounds = new Rectangle (xpos,
860 ypos + (row_count - page.Row) * (item_size.Height + spacing.Height),
861 width, item_size.Height);
863 if (page.Row != prev_row) {
864 if (SizeMode == TabSizeMode.FillToRight && !ShowSlider) {
865 FillRow (begin_prev, i - 1, ((row_width - TabPages [i - 1].TabBounds.Right) / (i - begin_prev)), spacing);
870 xpos += width + 1 + spacing.Width;
874 if (SizeMode == TabSizeMode.FillToRight && !ShowSlider) {
875 FillRow (begin_prev, TabPages.Count - 1,
876 ((row_width - TabPages [TabPages.Count - 1].TabBounds.Right) / (TabPages.Count - begin_prev)), spacing);
879 if (SelectedIndex != -1) {
880 ExpandSelected (TabPages [SelectedIndex], 2, row_width - 1);
884 private void FillRow (int start, int end, int amount, Size spacing)
886 int xpos = TabPages [start].TabBounds.Left;
887 for (int i = start; i <= end; i++) {
888 TabPage page = TabPages [i];
890 int width = (i == end ? Width - left - 3 : page.TabBounds.Width + amount);
892 page.TabBounds = new Rectangle (left, page.TabBounds.Top,
893 width, page.TabBounds.Height);
894 xpos = page.TabBounds.Right + 1 + spacing.Width;
898 private void FillRowV (int start, int end, int amount, Size spacing)
900 int ypos = TabPages [start].TabBounds.Top;
901 for (int i = start; i <= end; i++) {
902 TabPage page = TabPages [i];
904 int height = (i == end ? Height - top - 5 : page.TabBounds.Height + amount);
906 page.TabBounds = new Rectangle (page.TabBounds.Left, top,
907 page.TabBounds.Width, height);
908 ypos = page.TabBounds.Bottom + 1;
912 private void ExpandSelected (TabPage page, int left_edge, int right_edge)
914 if (Appearance != TabAppearance.Normal)
917 if (Alignment == TabAlignment.Top || Alignment == TabAlignment.Bottom) {
918 int l = page.TabBounds.Left - 4;
919 int r = page.TabBounds.Right + 4;
920 int y = page.TabBounds.Y;
921 int h = page.TabBounds.Height + 3;
925 if (r > right_edge && SizeMode != TabSizeMode.Normal)
927 if (Alignment == TabAlignment.Top)
929 if (Alignment == TabAlignment.Bottom)
932 page.TabBounds = new Rectangle (l, y, r - l, h);
934 int l = page.TabBounds.Left - 3;
935 int r = page.TabBounds.Right + 3;
936 int t = page.TabBounds.Top - 3;
937 int b = page.TabBounds.Bottom + 3;
944 page.TabBounds = new Rectangle (l, t, r - l, b - t);
948 private void PaintInternal (PaintEventArgs pe)
950 Draw (pe.Graphics, pe.ClipRectangle);
951 // On MS the Paint event never seems to be raised
954 private void Draw (Graphics dc, Rectangle clip)
956 ThemeEngine.Current.DrawTabControl (dc, clip, this);
959 private TabPage GetTab (int index)
961 return Controls [index] as TabPage;
964 private void SetTab (int index, TabPage value)
966 ((IList) Controls).Insert (index, value);
970 internal void Redraw ()
976 #endregion // Internal & Private Methods
980 [EditorBrowsable(EditorBrowsableState.Never)]
981 public new event EventHandler BackColorChanged {
982 add { base.BackColorChanged += value; }
983 remove { base.BackColorChanged -= value; }
987 [EditorBrowsable(EditorBrowsableState.Never)]
988 public new event EventHandler BackgroundImageChanged {
989 add { base.BackgroundImageChanged += value; }
990 remove { base.BackgroundImageChanged -= value; }
994 [EditorBrowsable(EditorBrowsableState.Never)]
995 public new event EventHandler ForeColorChanged {
996 add { base.ForeColorChanged += value; }
997 remove { base.ForeColorChanged -= value; }
1001 [EditorBrowsable(EditorBrowsableState.Never)]
1002 public new event PaintEventHandler Paint {
1003 add { base.Paint += value; }
1004 remove { base.Paint -= value; }
1008 [EditorBrowsable(EditorBrowsableState.Never)]
1009 public new event EventHandler TextChanged {
1010 add { base.TextChanged += value; }
1011 remove { base.TextChanged -= value; }
1014 public event DrawItemEventHandler DrawItem;
1015 public event EventHandler SelectedIndexChanged;
1016 #endregion // Events
1019 #region Class TabPage.ControlCollection
1020 public class ControlCollection : System.Windows.Forms.Control.ControlCollection {
1022 private TabControl owner;
1023 private ArrayList list = new ArrayList ();
1025 public ControlCollection (TabControl owner) : base (owner)
1030 public override void Add (Control value)
1032 if (!(value is TabPage))
1033 throw new ArgumentException ("Cannot add " +
1034 value.GetType ().Name + " to TabControl. " +
1035 "Only TabPages can be directly added to TabControls.");
1037 value.Visible = false;
1040 owner.SelectedIndex = 0;
1042 // Setting the selected index will calc the tab rows so
1043 // we don't need to do it again
1044 owner.ResizeTabPages ();
1048 #endregion // Class TabPage.ControlCollection
1050 #region Class TabPage.TabPageCollection
1051 public class TabPageCollection : IList, ICollection, IEnumerable {
1053 private TabControl owner;
1054 private IList controls;
1056 public TabPageCollection (TabControl owner)
1059 throw new ArgumentNullException ("Value cannot be null.");
1061 controls = owner.Controls;
1065 public virtual int Count {
1066 get { return owner.Controls.Count; }
1069 public virtual bool IsReadOnly {
1070 get { return false; }
1073 public virtual TabPage this [int index] {
1075 return owner.GetTab (index);
1078 owner.SetTab (index, value);
1082 bool ICollection.IsSynchronized {
1083 get { return false; }
1086 object ICollection.SyncRoot {
1087 get { return this; }
1090 bool IList.IsFixedSize {
1091 get { return false; }
1094 object IList.this [int index] {
1096 return owner.GetTab (index);
1099 owner.SetTab (index, (TabPage) value);
1103 public void Add (TabPage page)
1106 throw new ArgumentNullException ("Value cannot be null.");
1107 owner.Controls.Add (page);
1110 public void AddRange (TabPage [] pages)
1113 throw new ArgumentNullException ("Value cannot be null.");
1114 owner.Controls.AddRange (pages);
1117 public virtual void Clear ()
1119 owner.Controls.Clear ();
1122 public bool Contains (TabPage page)
1125 throw new ArgumentNullException ("Value cannot be null.");
1126 return owner.Controls.Contains (page);
1129 public virtual IEnumerator GetEnumerator ()
1131 return owner.Controls.GetEnumerator ();
1134 public int IndexOf (TabPage page)
1136 return owner.Controls.IndexOf (page);
1139 public void Remove (TabPage page)
1141 owner.Controls.Remove (page);
1144 public virtual void RemoveAt (int index)
1146 owner.Controls.RemoveAt (index);
1149 void ICollection.CopyTo (Array dest, int index)
1151 owner.Controls.CopyTo (dest, index);
1154 int IList.Add (object value)
1156 TabPage page = value as TabPage;
1158 throw new ArgumentException ("value");
1159 owner.Controls.Add (page);
1160 return owner.Controls.IndexOf (page);
1163 bool IList.Contains (object value)
1165 TabPage page = value as TabPage;
1168 return Contains (page);
1171 int IList.IndexOf (object value)
1173 TabPage page = value as TabPage;
1176 return IndexOf ((TabPage) page);
1179 void IList.Insert (int index, object value)
1181 throw new NotSupportedException ();
1184 void IList.Remove (object value)
1186 TabPage page = value as TabPage;
1189 Remove ((TabPage) value);
1192 #endregion // Class TabPage.TabPageCollection