Xamarin Public Jenkins (auto-signing) 468663ddbb Imported Upstream version 6.10.0.49
Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
2020-01-16 16:38:04 +00:00

2014 lines
50 KiB
C#

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (c) 2004-2005 Novell, Inc.
//
// Authors:
// Jackson Harper (jackson@ximian.com)
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms.Theming;
using System.Windows.Forms.VisualStyles;
namespace System.Windows.Forms {
[ComVisibleAttribute (true)]
[ClassInterfaceAttribute (ClassInterfaceType.AutoDispatch)]
[DefaultEvent("SelectedIndexChanged")]
[DefaultProperty("TabPages")]
[Designer("System.Windows.Forms.Design.TabControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
public class TabControl : Control {
#region Fields
private int selected_index = -1;
private TabAlignment alignment;
private TabAppearance appearance;
private TabDrawMode draw_mode;
private bool multiline;
private ImageList image_list;
private Size item_size = Size.Empty;
private bool item_size_manual;
private Point padding;
private int row_count = 0;
private bool hottrack;
private TabPageCollection tab_pages;
private bool show_tool_tips;
private TabSizeMode size_mode;
private bool show_slider = false;
private PushButtonState right_slider_state = PushButtonState.Normal;
private PushButtonState left_slider_state = PushButtonState.Normal;
private int slider_pos = 0;
TabPage entered_tab_page;
bool mouse_down_on_a_tab_page;
ToolTip tooltip;
ToolTip.TipState tooltip_state = ToolTip.TipState.Down;
Timer tooltip_timer;
private bool rightToLeftLayout;
#endregion // Fields
#region UIA Framework Events
static object UIAHorizontallyScrollableChangedEvent = new object ();
internal event EventHandler UIAHorizontallyScrollableChanged {
add { Events.AddHandler (UIAHorizontallyScrollableChangedEvent, value); }
remove { Events.RemoveHandler (UIAHorizontallyScrollableChangedEvent, value); }
}
internal void OnUIAHorizontallyScrollableChanged (EventArgs e)
{
EventHandler eh
= (EventHandler) Events [UIAHorizontallyScrollableChangedEvent];
if (eh != null)
eh (this, e);
}
static object UIAHorizontallyScrolledEvent = new object ();
internal event EventHandler UIAHorizontallyScrolled {
add { Events.AddHandler (UIAHorizontallyScrolledEvent, value); }
remove { Events.RemoveHandler (UIAHorizontallyScrolledEvent, value); }
}
internal void OnUIAHorizontallyScrolled (EventArgs e)
{
EventHandler eh
= (EventHandler) Events [UIAHorizontallyScrolledEvent];
if (eh != null)
eh (this, e);
}
#endregion
#region UIA Framework Property
internal double UIAHorizontalViewSize {
get { return LeftScrollButtonArea.Left * 100 / TabPages [TabCount - 1].TabBounds.Right; }
}
#endregion
#region Public Constructors
public TabControl ()
{
tab_pages = new TabPageCollection (this);
SetStyle (ControlStyles.UserPaint, false);
padding = ThemeEngine.Current.TabControlDefaultPadding;
MouseDown += new MouseEventHandler (MouseDownHandler);
MouseLeave += new EventHandler (OnMouseLeave);
MouseMove += new MouseEventHandler (OnMouseMove);
MouseUp += new MouseEventHandler (MouseUpHandler);
SizeChanged += new EventHandler (SizeChangedHandler);
}
#endregion // Public Constructors
#region Public Instance Properties
[DefaultValue(TabAlignment.Top)]
[Localizable(true)]
[RefreshProperties(RefreshProperties.All)]
public TabAlignment Alignment {
get { return alignment; }
set {
if (alignment == value)
return;
alignment = value;
if (alignment == TabAlignment.Left || alignment == TabAlignment.Right)
multiline = true;
Redraw ();
}
}
[DefaultValue(TabAppearance.Normal)]
[Localizable(true)]
public TabAppearance Appearance {
get { return appearance; }
set {
if (appearance == value)
return;
appearance = value;
Redraw ();
}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Color BackColor {
get { return ThemeEngine.Current.ColorControl; }
set { /* nothing happens on set on MS */ }
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Image BackgroundImage {
get { return base.BackgroundImage; }
set { base.BackgroundImage = value; }
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public override ImageLayout BackgroundImageLayout {
get { return base.BackgroundImageLayout; }
set { base.BackgroundImageLayout = value; }
}
public override Rectangle DisplayRectangle {
get {
return ThemeEngine.Current.TabControlGetDisplayRectangle (this);
}
}
[EditorBrowsable (EditorBrowsableState.Never)]
protected override bool DoubleBuffered {
get { return base.DoubleBuffered; }
set { base.DoubleBuffered = value; }
}
[DefaultValue(TabDrawMode.Normal)]
public TabDrawMode DrawMode {
get { return draw_mode; }
set {
if (draw_mode == value)
return;
draw_mode = value;
Redraw ();
}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Color ForeColor {
get { return base.ForeColor; }
set { base.ForeColor = value; }
}
[DefaultValue(false)]
public bool HotTrack {
get { return hottrack; }
set {
if (hottrack == value)
return;
hottrack = value;
Redraw ();
}
}
[RefreshProperties (RefreshProperties.Repaint)]
[DefaultValue(null)]
public ImageList ImageList {
get { return image_list; }
set {
image_list = value;
Redraw ();
}
}
[Localizable(true)]
public Size ItemSize {
get {
if (item_size_manual)
return item_size;
if (!IsHandleCreated)
return Size.Empty;
Size size = item_size;
if (SizeMode != TabSizeMode.Fixed) {
size.Width += padding.X * 2;
size.Height += padding.Y * 2;
}
if (tab_pages.Count == 0)
size.Width = 0;
return size;
}
set {
if (value.Height < 0 || value.Width < 0)
throw new ArgumentException ("'" + value + "' is not a valid value for 'ItemSize'.");
item_size = value;
item_size_manual = true;
Redraw ();
}
}
[DefaultValue(false)]
public bool Multiline {
get { return multiline; }
set {
if (multiline == value)
return;
multiline = value;
if (!multiline && alignment == TabAlignment.Left || alignment == TabAlignment.Right)
alignment = TabAlignment.Top;
Redraw ();
}
}
[Localizable(true)]
public
new
Point Padding {
get { return padding; }
set {
if (value.X < 0 || value.Y < 0)
throw new ArgumentException ("'" + value + "' is not a valid value for 'Padding'.");
if (padding == value)
return;
padding = value;
Redraw ();
}
}
[MonoTODO ("RTL not supported")]
[Localizable (true)]
[DefaultValue (false)]
public virtual bool RightToLeftLayout {
get { return this.rightToLeftLayout; }
set {
if (value != this.rightToLeftLayout) {
this.rightToLeftLayout = value;
this.OnRightToLeftLayoutChanged (EventArgs.Empty);
}
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int RowCount {
get { return row_count; }
}
[DefaultValue(-1)]
[Browsable(false)]
public int SelectedIndex {
get { return selected_index; }
set {
if (value < -1) {
throw new ArgumentOutOfRangeException ("SelectedIndex", "Value of '" + value + "' is valid for 'SelectedIndex'. " +
"'SelectedIndex' must be greater than or equal to -1.");
}
if (!this.IsHandleCreated) {
if (selected_index != value) {
selected_index = value;
}
return;
}
if (value >= TabCount) {
if (value != selected_index)
OnSelectedIndexChanged (EventArgs.Empty);
return;
}
if (value == selected_index) {
if (selected_index > -1)
Invalidate(GetTabRect (selected_index));
return;
}
TabControlCancelEventArgs ret = new TabControlCancelEventArgs (SelectedTab, selected_index, false, TabControlAction.Deselecting);
OnDeselecting (ret);
if (ret.Cancel)
return;
Focus ();
int old_index = selected_index;
int new_index = value;
selected_index = new_index;
ret = new TabControlCancelEventArgs (SelectedTab, selected_index, false, TabControlAction.Selecting);
OnSelecting (ret);
if (ret.Cancel) {
selected_index = old_index;
return;
}
SuspendLayout ();
Rectangle invalid = Rectangle.Empty;
bool refresh = false;
if (new_index != -1 && show_slider && new_index < slider_pos) {
slider_pos = new_index;
refresh = true;
}
if (new_index != -1) {
int le = TabPages[new_index].TabBounds.Right;
int re = LeftScrollButtonArea.Left;
if (show_slider && le > re) {
int i = 0;
for (i = 0; i < new_index; i++) {
if (TabPages [i].TabBounds.Left < 0) // tab scrolled off the visible area, ignore
continue;
if (TabPages [new_index].TabBounds.Right - TabPages[i].TabBounds.Right < re) {
i++;
break;
}
}
slider_pos = i;
refresh = true;
}
}
if (old_index != -1 && new_index != -1) {
if (!refresh)
invalid = GetTabRect (old_index);
((TabPage) Controls[old_index]).SetVisible (false);
}
TabPage selected = null;
if (new_index != -1) {
selected = (TabPage) Controls[new_index];
invalid = Rectangle.Union (invalid, GetTabRect (new_index));
selected.SetVisible (true);
}
OnSelectedIndexChanged (EventArgs.Empty);
ResumeLayout ();
if (refresh) {
SizeTabs ();
Refresh ();
} else if (new_index != -1 && selected.Row != BottomRow) {
DropRow (TabPages[new_index].Row);
// calculating what to invalidate here seems to be slower then just
// refreshing the whole thing
SizeTabs ();
Refresh ();
} else {
SizeTabs ();
// The lines are drawn on the edges of the tabs so the invalid area should
// needs to include the extra pixels of line width (but should not
// overflow the control bounds).
if (appearance == TabAppearance.Normal) {
invalid.Inflate (6, 4);
invalid.Intersect (ClientRectangle);
}
Invalidate (invalid);
}
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public TabPage SelectedTab {
get {
if (selected_index == -1)
return null;
return tab_pages [selected_index];
}
set {
int index = IndexForTabPage (value);
if (index == selected_index)
return;
SelectedIndex = index;
}
}
[DefaultValue(false)]
[Localizable(true)]
public bool ShowToolTips {
get { return show_tool_tips; }
set {
if (show_tool_tips == value)
return;
show_tool_tips = value;
}
}
[DefaultValue(TabSizeMode.Normal)]
[RefreshProperties(RefreshProperties.Repaint)]
public TabSizeMode SizeMode {
get { return size_mode; }
set {
if (size_mode == value)
return;
size_mode = value;
Redraw ();
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int TabCount {
get {
return tab_pages.Count;
}
}
[Editor ("System.Windows.Forms.Design.TabPageCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[MergableProperty(false)]
public TabPageCollection TabPages {
get { return tab_pages; }
}
[Browsable(false)]
[Bindable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override string Text {
get { return base.Text; }
set { base.Text = value; }
}
#endregion // Public Instance Properties
#region Internal Properties
internal bool ShowSlider {
get { return show_slider; }
set {
show_slider = value;
// UIA Framework Event: HorizontallyScrollable Changed
OnUIAHorizontallyScrollableChanged (EventArgs.Empty);
}
}
internal int SliderPos {
get { return slider_pos; }
}
internal PushButtonState RightSliderState {
get { return right_slider_state; }
private set {
if (right_slider_state == value)
return;
PushButtonState old_value = right_slider_state;
right_slider_state = value;
if (NeedsToInvalidateScrollButton (old_value, value))
Invalidate (RightScrollButtonArea);
}
}
internal PushButtonState LeftSliderState {
get { return left_slider_state; }
set {
if (left_slider_state == value)
return;
PushButtonState old_value = left_slider_state;
left_slider_state = value;
if (NeedsToInvalidateScrollButton (old_value, value))
Invalidate (LeftScrollButtonArea);
}
}
bool NeedsToInvalidateScrollButton (PushButtonState oldState, PushButtonState newState)
{
if ((oldState == PushButtonState.Hot && newState == PushButtonState.Normal) ||
(oldState == PushButtonState.Normal && newState == PushButtonState.Hot))
return HasHotElementStyles;
return true;
}
internal TabPage EnteredTabPage {
get { return entered_tab_page; }
private set {
if (entered_tab_page == value)
return;
if (HasHotElementStyles) {
Region area_to_invalidate = new Region ();
area_to_invalidate.MakeEmpty ();
if (entered_tab_page != null)
area_to_invalidate.Union (entered_tab_page.TabBounds);
entered_tab_page = value;
if (entered_tab_page != null)
area_to_invalidate.Union (entered_tab_page.TabBounds);
Invalidate (area_to_invalidate);
area_to_invalidate.Dispose ();
} else
entered_tab_page = value;
if (value == null)
CloseToolTip ();
else
SetToolTip (GetToolTipText (value));
}
}
#endregion // Internal Properties
#region Protected Instance Properties
protected override CreateParams CreateParams {
get {
CreateParams c = base.CreateParams;
return c;
}
}
protected override Size DefaultSize {
get { return new Size (200, 100); }
}
#endregion // Protected Instance Properties
#region Public Instance Methods
public Rectangle GetTabRect (int index)
{
TabPage page = GetTab (index);
return page.TabBounds;
}
public Control GetControl (int index)
{
return GetTab (index);
}
public void SelectTab (TabPage tabPage)
{
if (tabPage == null)
throw new ArgumentNullException ("tabPage");
SelectTab (this.tab_pages [tabPage]);
}
public void SelectTab (string tabPageName)
{
if (tabPageName == null)
throw new ArgumentNullException ("tabPageName");
SelectTab (this.tab_pages [tabPageName]);
}
public void SelectTab (int index)
{
if (index < 0 || index > this.tab_pages.Count - 1)
throw new ArgumentOutOfRangeException ("index");
SelectedIndex = index;
}
public void DeselectTab (TabPage tabPage)
{
if (tabPage == null)
throw new ArgumentNullException ("tabPage");
DeselectTab (this.tab_pages [tabPage]);
}
public void DeselectTab (string tabPageName)
{
if (tabPageName == null)
throw new ArgumentNullException ("tabPageName");
DeselectTab (this.tab_pages [tabPageName]);
}
public void DeselectTab (int index)
{
if (index == SelectedIndex) {
if (index >= 0 && index < this.tab_pages.Count - 1)
SelectedIndex = ++index;
else
SelectedIndex = 0;
}
}
public override string ToString ()
{
string res = String.Concat (base.ToString (),
", TabPages.Count: ",
TabCount);
if (TabCount > 0)
res = String.Concat (res, ", TabPages[0]: ",
TabPages [0]);
return res;
}
#endregion // Public Instance Methods
#region Protected Instance Methods
#region Handles
protected override Control.ControlCollection CreateControlsInstance ()
{
return new TabControl.ControlCollection (this);
}
protected override void CreateHandle ()
{
base.CreateHandle ();
selected_index = (selected_index >= TabCount ? (TabCount > 0 ? 0 : -1) : selected_index);
if (TabCount > 0) {
if (selected_index > -1)
this.SelectedTab.SetVisible(true);
else
tab_pages[0].SetVisible(true);
}
ResizeTabPages ();
}
protected override void OnHandleCreated (EventArgs e)
{
base.OnHandleCreated (e);
}
protected override void OnHandleDestroyed (EventArgs e)
{
base.OnHandleDestroyed (e);
}
protected override void Dispose (bool disposing)
{
if (tooltip_timer != null)
tooltip_timer.Dispose();
if (tooltip != null)
tooltip.Dispose();
base.Dispose (disposing);
}
#endregion
#region Events
protected virtual void OnDrawItem (DrawItemEventArgs e)
{
if (DrawMode != TabDrawMode.OwnerDrawFixed)
return;
DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
if (eh != null)
eh (this, e);
}
internal void OnDrawItemInternal (DrawItemEventArgs e)
{
OnDrawItem (e);
}
protected override void OnFontChanged (EventArgs e)
{
base.OnFontChanged (e);
ResizeTabPages ();
}
protected override void OnResize (EventArgs e)
{
base.OnResize (e);
}
protected override void OnStyleChanged (EventArgs e)
{
base.OnStyleChanged (e);
}
protected virtual void OnSelectedIndexChanged (EventArgs e)
{
EventHandler eh = (EventHandler) (Events[SelectedIndexChangedEvent]);
if (eh != null)
eh (this, e);
}
internal override void OnPaintInternal (PaintEventArgs pe)
{
if (GetStyle (ControlStyles.UserPaint))
return;
Draw (pe.Graphics, pe.ClipRectangle);
pe.Handled = true;
}
protected override void OnEnter (EventArgs e)
{
base.OnEnter (e);
if (SelectedTab != null)
SelectedTab.FireEnter ();
}
protected override void OnLeave (EventArgs e)
{
if (SelectedTab != null)
SelectedTab.FireLeave ();
base.OnLeave (e);
}
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected virtual void OnRightToLeftLayoutChanged (EventArgs e)
{
EventHandler eh = (EventHandler) (Events[RightToLeftLayoutChangedEvent]);
if (eh != null)
eh (this, e);
}
[EditorBrowsable (EditorBrowsableState.Never)]
protected override void ScaleCore (float dx, float dy)
{
base.ScaleCore (dx, dy);
}
protected virtual void OnDeselecting (TabControlCancelEventArgs e)
{
TabControlCancelEventHandler eh = (TabControlCancelEventHandler) (Events[DeselectingEvent]);
if (eh != null)
eh (this, e);
if (!e.Cancel)
OnDeselected (new TabControlEventArgs (SelectedTab, selected_index, TabControlAction.Deselected));
}
protected virtual void OnDeselected (TabControlEventArgs e)
{
TabControlEventHandler eh = (TabControlEventHandler) (Events[DeselectedEvent]);
if (eh != null)
eh (this, e);
if (this.SelectedTab != null)
this.SelectedTab.FireLeave ();
}
protected virtual void OnSelecting (TabControlCancelEventArgs e)
{
TabControlCancelEventHandler eh = (TabControlCancelEventHandler) (Events[SelectingEvent]);
if (eh != null)
eh (this, e);
if (!e.Cancel)
OnSelected (new TabControlEventArgs (SelectedTab, selected_index, TabControlAction.Selected));
}
protected virtual void OnSelected (TabControlEventArgs e)
{
TabControlEventHandler eh = (TabControlEventHandler) (Events[SelectedEvent]);
if (eh != null)
eh (this, e);
if (this.SelectedTab != null)
this.SelectedTab.FireEnter ();
}
#endregion
#region Keys
protected override bool ProcessKeyPreview (ref Message m)
{
return base.ProcessKeyPreview (ref m);
}
protected override void OnKeyDown (KeyEventArgs ke)
{
base.OnKeyDown (ke);
if (ke.Handled)
return;
if (ke.KeyCode == Keys.Tab && (ke.KeyData & Keys.Control) != 0) {
if ((ke.KeyData & Keys.Shift) == 0)
SelectedIndex = (SelectedIndex + 1) % TabCount;
else
SelectedIndex = (SelectedIndex + TabCount - 1) % TabCount;
ke.Handled = true;
} else if (ke.KeyCode == Keys.PageUp && (ke.KeyData & Keys.Control) != 0) {
SelectedIndex = (SelectedIndex + TabCount - 1) % TabCount;
ke.Handled = true;
} else if (ke.KeyCode == Keys.PageDown && (ke.KeyData & Keys.Control) != 0) {
SelectedIndex = (SelectedIndex + 1) % TabCount;
ke.Handled = true;
} else if (ke.KeyCode == Keys.Home) {
SelectedIndex = 0;
ke.Handled = true;
} else if (ke.KeyCode == Keys.End) {
SelectedIndex = TabCount - 1;
ke.Handled = true;
} else if (NavigateTabs (ke.KeyCode))
ke.Handled = true;
}
protected override bool IsInputKey (Keys keyData)
{
switch (keyData & Keys.KeyCode) {
case Keys.Home:
case Keys.End:
case Keys.Left:
case Keys.Right:
case Keys.Up:
case Keys.Down:
return true;
}
return base.IsInputKey (keyData);
}
private bool NavigateTabs (Keys keycode)
{
bool move_left = false;
bool move_right = false;
if (alignment == TabAlignment.Bottom || alignment == TabAlignment.Top) {
if (keycode == Keys.Left)
move_left = true;
else if (keycode == Keys.Right)
move_right = true;
} else {
if (keycode == Keys.Up)
move_left = true;
else if (keycode == Keys.Down)
move_right = true;
}
if (move_left) {
if (SelectedIndex > 0) {
SelectedIndex--;
return true;
}
}
if (move_right) {
if (SelectedIndex < TabCount - 1) {
SelectedIndex++;
return true;
}
}
return false;
}
#endregion
#region Pages Collection
protected void RemoveAll ()
{
Controls.Clear ();
}
protected virtual object [] GetItems ()
{
TabPage [] pages = new TabPage [Controls.Count];
Controls.CopyTo (pages, 0);
return pages;
}
protected virtual object [] GetItems (Type baseType)
{
object[] pages = (object[])Array.CreateInstance (baseType, Controls.Count);
Controls.CopyTo (pages, 0);
return pages;
}
#endregion
protected void UpdateTabSelection (bool updateFocus)
{
ResizeTabPages ();
}
protected string GetToolTipText (object item)
{
TabPage page = (TabPage) item;
return page.ToolTipText;
}
protected override void WndProc (ref Message m)
{
switch ((Msg)m.Msg) {
case Msg.WM_SETFOCUS:
if (selected_index != -1)
Invalidate(GetTabRect(selected_index));
base.WndProc (ref m);
break;
case Msg.WM_KILLFOCUS:
if (selected_index != -1)
Invalidate(GetTabRect(selected_index));
base.WndProc (ref m);
break;
default:
base.WndProc (ref m);
break;
}
}
#endregion // Protected Instance Methods
#region Internal & Private Methods
private bool CanScrollRight {
get {
return (slider_pos < TabCount - 1);
}
}
private bool CanScrollLeft {
get { return slider_pos > 0; }
}
private void MouseDownHandler (object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == 0)
return;
if (ShowSlider) {
Rectangle right = RightScrollButtonArea;
Rectangle left = LeftScrollButtonArea;
if (right.Contains (e.X, e.Y)) {
right_slider_state = PushButtonState.Pressed;
if (CanScrollRight) {
slider_pos++;
SizeTabs ();
// UIA Framework Event: Horizontally Scrolled
OnUIAHorizontallyScrolled (EventArgs.Empty);
switch (this.Alignment) {
case TabAlignment.Top:
Invalidate (new Rectangle (0, 0, Width, ItemSize.Height));
break;
case TabAlignment.Bottom:
Invalidate (new Rectangle (0, DisplayRectangle.Bottom, Width, Height - DisplayRectangle.Bottom));
break;
case TabAlignment.Left:
Invalidate (new Rectangle (0, 0, DisplayRectangle.Left, Height));
break;
case TabAlignment.Right:
Invalidate (new Rectangle (DisplayRectangle.Right, 0, Width - DisplayRectangle.Right, Height));
break;
}
} else {
Invalidate (right);
}
return;
} else if (left.Contains (e.X, e.Y)) {
left_slider_state = PushButtonState.Pressed;
if (CanScrollLeft) {
slider_pos--;
SizeTabs ();
// UIA Framework Event: Horizontally Scrolled
OnUIAHorizontallyScrolled (EventArgs.Empty);
switch (this.Alignment) {
case TabAlignment.Top:
Invalidate (new Rectangle (0, 0, Width, ItemSize.Height));
break;
case TabAlignment.Bottom:
Invalidate (new Rectangle (0, DisplayRectangle.Bottom, Width, Height - DisplayRectangle.Bottom));
break;
case TabAlignment.Left:
Invalidate (new Rectangle (0, 0, DisplayRectangle.Left, Height));
break;
case TabAlignment.Right:
Invalidate (new Rectangle (DisplayRectangle.Right, 0, Width - DisplayRectangle.Right, Height));
break;
}
} else {
Invalidate (left);
}
return;
}
}
int count = Controls.Count;
for (int i = SliderPos; i < count; i++) {
if (!GetTabRect (i).Contains (e.X, e.Y))
continue;
SelectedIndex = i;
mouse_down_on_a_tab_page = true;
break;
}
}
private void MouseUpHandler (object sender, MouseEventArgs e)
{
mouse_down_on_a_tab_page = false;
if (ShowSlider && (left_slider_state == PushButtonState.Pressed || right_slider_state == PushButtonState.Pressed)) {
Rectangle invalid;
if (left_slider_state == PushButtonState.Pressed) {
invalid = LeftScrollButtonArea;
left_slider_state = GetScrollButtonState (invalid, e.Location);
} else {
invalid = RightScrollButtonArea;
right_slider_state = GetScrollButtonState (invalid, e.Location);
}
Invalidate (invalid);
}
}
bool HasHotElementStyles {
get {
return ThemeElements.CurrentTheme.TabControlPainter.HasHotElementStyles (this);
}
}
Rectangle LeftScrollButtonArea {
get {
return ThemeElements.CurrentTheme.TabControlPainter.GetLeftScrollRect (this);
}
}
Rectangle RightScrollButtonArea {
get {
return ThemeElements.CurrentTheme.TabControlPainter.GetRightScrollRect (this);
}
}
static PushButtonState GetScrollButtonState (Rectangle scrollButtonArea, Point cursorLocation)
{
return scrollButtonArea.Contains (cursorLocation) ? PushButtonState.Hot : PushButtonState.Normal;
}
private void SizeChangedHandler (object sender, EventArgs e)
{
Redraw ();
}
internal int IndexForTabPage (TabPage page)
{
for (int i = 0; i < tab_pages.Count; i++) {
if (page == tab_pages [i])
return i;
}
return -1;
}
private void ResizeTabPages ()
{
CalcTabRows ();
SizeTabs ();
Rectangle r = DisplayRectangle;
foreach (TabPage page in Controls) {
page.Bounds = r;
}
}
private int MinimumTabWidth {
get {
return ThemeEngine.Current.TabControlMinimumTabWidth;
}
}
private Size TabSpacing {
get {
return ThemeEngine.Current.TabControlGetSpacing (this);
}
}
private void CalcTabRows ()
{
switch (Alignment) {
case TabAlignment.Right:
case TabAlignment.Left:
CalcTabRows (Height);
break;
default:
CalcTabRows (Width);
break;
}
}
private void CalcTabRows (int row_width)
{
int xpos = 0;
int ypos = 0;
Size spacing = TabSpacing;
if (TabPages.Count > 0)
row_count = 1;
show_slider = false;
CalculateItemSize ();
for (int i = 0; i < TabPages.Count; i++) {
TabPage page = TabPages [i];
int aux = 0;
SizeTab (page, i, row_width, ref xpos, ref ypos, spacing, 0, ref aux, true);
}
if (SelectedIndex != -1 && TabPages.Count > SelectedIndex && TabPages[SelectedIndex].Row != BottomRow)
DropRow (TabPages [SelectedIndex].Row);
}
// ItemSize per-se is used mostly only to retrieve the Height,
// since the actual Width of the tabs is computed individually,
// except when SizeMode is TabSizeMode.Fixed, where Width is used as well.
private void CalculateItemSize ()
{
if (item_size_manual)
return;
SizeF size;
if (tab_pages.Count > 0) {
// .Net uses the first tab page if available.
size = TextRenderer.MeasureString (tab_pages [0].Text, Font);
} else {
size = TextRenderer.MeasureString ("a", Font);
size.Width = 0;
}
if (size_mode == TabSizeMode.Fixed)
size.Width = 96;
if (size.Width < MinimumTabWidth)
size.Width = MinimumTabWidth;
if (image_list != null && image_list.ImageSize.Height > size.Height)
size.Height = image_list.ImageSize.Height;
item_size = size.ToSize ();
}
private int BottomRow {
get { return 1; }
}
private int Direction
{
get {
return 1;
}
}
private void DropRow (int row)
{
if (Appearance != TabAppearance.Normal)
return;
int bottom = BottomRow;
int direction = Direction;
foreach (TabPage page in TabPages) {
if (page.Row == row) {
page.Row = bottom;
} else if (direction == 1 && page.Row < row) {
page.Row += direction;
} else if (direction == -1 && page.Row > row) {
page.Row += direction;
}
}
}
private int CalcYPos ()
{
if (Alignment == TabAlignment.Bottom || Alignment == TabAlignment.Left)
return ThemeEngine.Current.TabControlGetPanelRect (this).Bottom;
if (Appearance == TabAppearance.Normal)
return this.ClientRectangle.Y + ThemeEngine.Current.TabControlSelectedDelta.Y;
return this.ClientRectangle.Y;
}
private int CalcXPos ()
{
if (Alignment == TabAlignment.Right)
return ThemeEngine.Current.TabControlGetPanelRect (this).Right;
if (Appearance == TabAppearance.Normal)
return this.ClientRectangle.X + ThemeEngine.Current.TabControlSelectedDelta.X;
return this.ClientRectangle.X;
}
private void SizeTabs ()
{
switch (Alignment) {
case TabAlignment.Right:
case TabAlignment.Left:
SizeTabs (Height, true);
break;
default:
SizeTabs (Width, false);
break;
}
}
private void SizeTabs (int row_width, bool vertical)
{
int ypos = 0;
int xpos = 0;
int prev_row = 1;
Size spacing = TabSpacing;
int begin_prev = 0;
if (TabPages.Count == 0)
return;
prev_row = TabPages [0].Row;
// Reset the slider position if the slider isn't needed
// anymore (ie window size was increased so all tabs are visible)
if (!show_slider)
slider_pos = 0;
else {
// set X = -1 for marking tabs that are not visible due to scrolling
for (int i = 0; i < slider_pos; i++) {
TabPage page = TabPages[i];
Rectangle x = page.TabBounds;
x.X = -1;
page.TabBounds = x;
}
}
for (int i = slider_pos; i < TabPages.Count; i++) {
TabPage page = TabPages[i];
SizeTab (page, i, row_width, ref xpos, ref ypos, spacing, prev_row, ref begin_prev, false);
prev_row = page.Row;
}
if (SizeMode == TabSizeMode.FillToRight && !ShowSlider) {
FillRow (begin_prev, TabPages.Count - 1,
((row_width - TabPages [TabPages.Count - 1].TabBounds.Right) / (TabPages.Count - begin_prev)),
spacing, vertical);
}
if (SelectedIndex != -1) {
ExpandSelected (TabPages [SelectedIndex], 0, row_width - 1);
}
}
private void SizeTab (TabPage page, int i, int row_width, ref int xpos, ref int ypos,
Size spacing, int prev_row, ref int begin_prev, bool widthOnly)
{
int width, height = 0;
if (SizeMode == TabSizeMode.Fixed) {
width = item_size.Width;
} else {
width = MeasureStringWidth (DeviceContext, page.Text, Font);
width += (Padding.X * 2) + 2;
if (ImageList != null && page.ImageIndex >= 0) {
width += ImageList.ImageSize.Width + ThemeEngine.Current.TabControlImagePadding.X;
int image_size = ImageList.ImageSize.Height + ThemeEngine.Current.TabControlImagePadding.Y;
if (item_size.Height < image_size)
item_size.Height = image_size;
}
if (width < MinimumTabWidth)
width = MinimumTabWidth;
}
// Use ItemSize property to recover the padding info as well.
height = ItemSize.Height - ThemeEngine.Current.TabControlSelectedDelta.Height; // full height only for selected tab
if (i == SelectedIndex)
width += ThemeEngine.Current.TabControlSelectedSpacing;
if (widthOnly) {
page.TabBounds = new Rectangle (xpos, 0, width, 0);
if (xpos + width > row_width && multiline) {
xpos = 0;
row_count++;
} else if (xpos + width > row_width) {
show_slider = true;
}
page.Row = row_count;
if (i == selected_index && show_slider) {
for (int j = i-1; j >= 0; j--) {
if (TabPages [j].TabBounds.Left < xpos + width - row_width) {
slider_pos = j+1;
break;
}
}
}
} else {
if (page.Row != prev_row) {
xpos = 0;
}
switch (Alignment) {
case TabAlignment.Top:
case TabAlignment.Bottom:
page.TabBounds = new Rectangle (
xpos + CalcXPos (),
ypos + (height + spacing.Height) * (row_count - page.Row) + CalcYPos (),
width,
height);
break;
case TabAlignment.Left:
if (Appearance == TabAppearance.Normal) {
// tab rows are positioned right to left
page.TabBounds = new Rectangle (
ypos + (height + spacing.Height) * (row_count - page.Row) + CalcXPos (),
xpos,
height,
width);
} else {
// tab rows are positioned left to right
page.TabBounds = new Rectangle (
ypos + (height + spacing.Height) * (page.Row - 1) + CalcXPos (),
xpos,
height,
width);
}
break;
case TabAlignment.Right:
if (Appearance == TabAppearance.Normal) {
// tab rows are positioned left to right
page.TabBounds = new Rectangle (
ypos + (height + spacing.Height) * (page.Row - 1) + CalcXPos (),
xpos,
height,
width);
} else {
// tab rows are positioned right to left
page.TabBounds = new Rectangle (
ypos + (height + spacing.Height) * (row_count - page.Row) + CalcXPos (),
xpos,
height,
width);
}
break;
}
if (page.Row != prev_row) {
if (SizeMode == TabSizeMode.FillToRight && !ShowSlider) {
bool vertical = alignment == TabAlignment.Right || alignment == TabAlignment.Left;
int offset = vertical ? TabPages [i - 1].TabBounds.Bottom : TabPages [i - 1].TabBounds.Right;
FillRow (begin_prev, i - 1, ((row_width - offset) / (i - begin_prev)), spacing,
vertical);
}
begin_prev = i;
}
}
xpos += width + spacing.Width + ThemeEngine.Current.TabControlColSpacing;
}
private void FillRow (int start, int end, int amount, Size spacing, bool vertical)
{
if (vertical)
FillRowV (start, end, amount, spacing);
else
FillRow (start, end, amount, spacing);
}
private void FillRow (int start, int end, int amount, Size spacing)
{
int xpos = TabPages [start].TabBounds.Left;
for (int i = start; i <= end; i++) {
TabPage page = TabPages [i];
int left = xpos;
int width = (i == end ? Width - left - 3 : page.TabBounds.Width + amount);
page.TabBounds = new Rectangle (left, page.TabBounds.Top,
width, page.TabBounds.Height);
xpos = page.TabBounds.Right + 1 + spacing.Width;
}
}
private void FillRowV (int start, int end, int amount, Size spacing)
{
int ypos = TabPages [start].TabBounds.Top;
for (int i = start; i <= end; i++) {
TabPage page = TabPages [i];
int top = ypos;
int height = (i == end ? Height - top - 5 : page.TabBounds.Height + amount);
page.TabBounds = new Rectangle (page.TabBounds.Left, top,
page.TabBounds.Width, height);
ypos = page.TabBounds.Bottom + 1;
}
}
private void ExpandSelected (TabPage page, int left_edge, int right_edge)
{
if (Appearance != TabAppearance.Normal)
return;
Rectangle r = page.TabBounds;
r.Y -= ThemeEngine.Current.TabControlSelectedDelta.Y;
r.X -= ThemeEngine.Current.TabControlSelectedDelta.X;
r.Width += ThemeEngine.Current.TabControlSelectedDelta.Width;
r.Height += ThemeEngine.Current.TabControlSelectedDelta.Height;
if (r.Left < left_edge)
r.X = left_edge;
// Adjustment can't be used for right alignment, since it is
// the only one that has a different X origin than 0
if (r.Right > right_edge && SizeMode != TabSizeMode.Normal &&
alignment != TabAlignment.Right)
r.Width = right_edge - r.X;
page.TabBounds = r;
}
private void Draw (Graphics dc, Rectangle clip)
{
ThemeEngine.Current.DrawTabControl (dc, clip, this);
}
private TabPage GetTab (int index)
{
return Controls [index] as TabPage;
}
private void SetTab (int index, TabPage value)
{
if (!tab_pages.Contains (value)) {
this.Controls.Add (value);
}
this.Controls.RemoveAt (index);
this.Controls.SetChildIndex (value, index);
Redraw ();
}
private void InsertTab (int index, TabPage value)
{
if (!tab_pages.Contains (value)) {
this.Controls.Add (value);
}
this.Controls.SetChildIndex (value, index);
Redraw ();
}
internal void Redraw ()
{
if (!IsHandleCreated)
return;
ResizeTabPages ();
Refresh ();
}
private int MeasureStringWidth (Graphics graphics, string text, Font font)
{
if (text == String.Empty)
return 0;
StringFormat format = new StringFormat();
RectangleF rect = new RectangleF(0, 0, 1000, 1000);
CharacterRange[] ranges = { new CharacterRange(0, text.Length) };
Region[] regions = new Region[1];
format.SetMeasurableCharacterRanges(ranges);
format.FormatFlags = StringFormatFlags.NoClip;
format.FormatFlags |= StringFormatFlags.NoWrap;
regions = graphics.MeasureCharacterRanges(text + "I", font, rect, format);
rect = regions[0].GetBounds(graphics);
return (int)(rect.Width);
}
void SetToolTip (string text)
{
if (!show_tool_tips)
return;
if (text == null || text.Length == 0) {
CloseToolTip ();
return;
}
if (tooltip == null) {
tooltip = new ToolTip ();
tooltip_timer = new Timer ();
tooltip_timer.Tick += new EventHandler (ToolTipTimerTick);
}
CloseToolTip ();
tooltip_state = ToolTip.TipState.Initial;
tooltip_timer.Interval = 500;
tooltip_timer.Start ();
}
void CloseToolTip ()
{
if (tooltip == null)
return;
tooltip.Hide (this);
tooltip_timer.Stop ();
tooltip_state = ToolTip.TipState.Down;
}
void ToolTipTimerTick (object o, EventArgs args)
{
switch (tooltip_state) {
case ToolTip.TipState.Initial:
tooltip_timer.Stop ();
tooltip_timer.Interval = 5000;
tooltip_timer.Start ();
tooltip_state = ToolTip.TipState.Show;
tooltip.Present (this, GetToolTipText (EnteredTabPage));
break;
case ToolTip.TipState.Show:
CloseToolTip ();
break;
}
}
void OnMouseMove (object sender, MouseEventArgs e)
{
if (!mouse_down_on_a_tab_page && ShowSlider) {
if (LeftSliderState == PushButtonState.Pressed ||
RightSliderState == PushButtonState.Pressed)
return;
if (LeftScrollButtonArea.Contains (e.Location)) {
LeftSliderState = PushButtonState.Hot;
RightSliderState = PushButtonState.Normal;
EnteredTabPage = null;
return;
}
if (RightScrollButtonArea.Contains (e.Location)) {
RightSliderState = PushButtonState.Hot;
LeftSliderState = PushButtonState.Normal;
EnteredTabPage = null;
return;
}
LeftSliderState = PushButtonState.Normal;
RightSliderState = PushButtonState.Normal;
}
if (EnteredTabPage != null && EnteredTabPage.TabBounds.Contains (e.Location))
return;
for (int index = 0; index < TabCount; index++) {
TabPage tab_page = TabPages[index];
if (tab_page.TabBounds.Contains (e.Location)) {
EnteredTabPage = tab_page;
return;
}
}
EnteredTabPage = null;
}
void OnMouseLeave (object sender, EventArgs e)
{
if (ShowSlider) {
LeftSliderState = PushButtonState.Normal;
RightSliderState = PushButtonState.Normal;
}
EnteredTabPage = null;
}
#endregion // Internal & Private Methods
#region Events
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler BackColorChanged {
add { base.BackColorChanged += value; }
remove { base.BackColorChanged -= value; }
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler BackgroundImageChanged {
add { base.BackgroundImageChanged += value; }
remove { base.BackgroundImageChanged -= value; }
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public new event EventHandler BackgroundImageLayoutChanged
{
add { base.BackgroundImageLayoutChanged += value; }
remove { base.BackgroundImageLayoutChanged -= value; }
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler ForeColorChanged {
add { base.ForeColorChanged += value; }
remove { base.ForeColorChanged -= value; }
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event PaintEventHandler Paint {
add { base.Paint += value; }
remove { base.Paint -= value; }
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler TextChanged {
add { base.TextChanged += value; }
remove { base.TextChanged -= value; }
}
static object DrawItemEvent = new object ();
static object SelectedIndexChangedEvent = new object ();
public event DrawItemEventHandler DrawItem {
add { Events.AddHandler (DrawItemEvent, value); }
remove { Events.RemoveHandler (DrawItemEvent, value); }
}
public event EventHandler SelectedIndexChanged {
add { Events.AddHandler (SelectedIndexChangedEvent, value); }
remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
}
static object SelectedEvent = new object ();
public event TabControlEventHandler Selected {
add { Events.AddHandler (SelectedEvent, value); }
remove { Events.RemoveHandler (SelectedEvent, value); }
}
static object DeselectedEvent = new object ();
public event TabControlEventHandler Deselected
{
add { Events.AddHandler (DeselectedEvent, value); }
remove { Events.RemoveHandler (DeselectedEvent, value); }
}
static object SelectingEvent = new object ();
public event TabControlCancelEventHandler Selecting
{
add { Events.AddHandler (SelectingEvent, value); }
remove { Events.RemoveHandler (SelectingEvent, value); }
}
static object DeselectingEvent = new object ();
public event TabControlCancelEventHandler Deselecting
{
add { Events.AddHandler (DeselectingEvent, value); }
remove { Events.RemoveHandler (DeselectingEvent, value); }
}
static object RightToLeftLayoutChangedEvent = new object ();
public event EventHandler RightToLeftLayoutChanged
{
add { Events.AddHandler (RightToLeftLayoutChangedEvent, value); }
remove { Events.RemoveHandler (RightToLeftLayoutChangedEvent, value); }
}
#endregion // Events
#region Class TaControl.ControlCollection
[ComVisible (false)]
public new class ControlCollection : System.Windows.Forms.Control.ControlCollection {
private TabControl owner;
public ControlCollection (TabControl owner) : base (owner)
{
this.owner = owner;
}
public override void Add (Control value)
{
TabPage page = value as TabPage;
if (page == null)
throw new ArgumentException ("Cannot add " +
value.GetType ().Name + " to TabControl. " +
"Only TabPages can be directly added to TabControls.");
page.SetVisible (false);
base.Add (value);
if (owner.TabCount == 1 && owner.selected_index < 0)
owner.SelectedIndex = 0;
owner.Redraw ();
}
public override void Remove (Control value)
{
bool invalid_selected_index = false;
TabPage page = value as TabPage;
int next_selected_index = -1;
if (page != null && owner.Controls.Contains (page)) {
int index = owner.IndexForTabPage (page);
if (owner.SelectedIndex < index || owner.SelectedIndex == 0)
next_selected_index = owner.SelectedIndex;
else
next_selected_index = owner.SelectedIndex - 1;
owner.selected_index = -1; // Invalidate internal selected Index
invalid_selected_index = true;
}
base.Remove (value);
// We don't want to raise SelectedIndexChanged until after we
// have removed from the collection, so TabCount will be
// correct for the user.
if (invalid_selected_index) {
if (Count > 0)
owner.SelectedIndex = next_selected_index;
else // Count == 0
owner.OnSelectedIndexChanged (EventArgs.Empty);
owner.Invalidate ();
} else
owner.Redraw ();
}
}
#endregion // Class TabControl.ControlCollection
#region Class TabPage.TabPageCollection
public class TabPageCollection : IList, ICollection, IEnumerable {
private TabControl owner;
public TabPageCollection (TabControl owner)
{
if (owner == null)
throw new ArgumentNullException ("Value cannot be null.");
this.owner = owner;
}
[Browsable(false)]
public int Count {
get { return owner.Controls.Count; }
}
public bool IsReadOnly {
get { return false; }
}
public virtual TabPage this [int index] {
get {
return owner.GetTab (index);
}
set {
owner.SetTab (index, value);
}
}
public virtual TabPage this [string key] {
get {
if (string.IsNullOrEmpty (key))
return null;
int index = this.IndexOfKey (key);
if (index < 0 || index >= this.Count)
return null;
return this[index];
}
}
internal int this[TabPage tabPage] {
get {
if (tabPage == null)
return -1;
for (int i = 0; i < this.Count; i++)
if (this[i].Equals (tabPage))
return i;
return -1;
}
}
bool ICollection.IsSynchronized {
get { return false; }
}
object ICollection.SyncRoot {
get { return this; }
}
bool IList.IsFixedSize {
get { return false; }
}
object IList.this [int index] {
get {
return owner.GetTab (index);
}
set {
owner.SetTab (index, (TabPage) value);
}
}
public void Add (TabPage value)
{
if (value == null)
throw new ArgumentNullException ("Value cannot be null.");
owner.Controls.Add (value);
}
public void Add (string text)
{
TabPage page = new TabPage (text);
this.Add (page);
}
public void Add (string key, string text)
{
TabPage page = new TabPage (text);
page.Name = key;
this.Add (page);
}
public void Add (string key, string text, int imageIndex)
{
TabPage page = new TabPage (text);
page.Name = key;
page.ImageIndex = imageIndex;
this.Add (page);
}
// .Net sets the ImageKey, but does not show the image when this is used
public void Add (string key, string text, string imageKey)
{
TabPage page = new TabPage (text);
page.Name = key;
page.ImageKey = imageKey;
this.Add (page);
}
public void AddRange (TabPage [] pages)
{
if (pages == null)
throw new ArgumentNullException ("Value cannot be null.");
owner.Controls.AddRange (pages);
}
public virtual void Clear ()
{
owner.Controls.Clear ();
owner.Invalidate ();
}
public bool Contains (TabPage page)
{
if (page == null)
throw new ArgumentNullException ("Value cannot be null.");
return owner.Controls.Contains (page);
}
public virtual bool ContainsKey (string key)
{
int index = this.IndexOfKey (key);
return (index >= 0 && index < this.Count);
}
public IEnumerator GetEnumerator ()
{
return owner.Controls.GetEnumerator ();
}
public int IndexOf (TabPage page)
{
return owner.Controls.IndexOf (page);
}
public virtual int IndexOfKey(string key)
{
if (string.IsNullOrEmpty (key))
return -1;
for (int i = 0; i < this.Count; i++) {
if (string.Compare (this[i].Name, key, true,
System.Globalization.CultureInfo.InvariantCulture) == 0) {
return i;
}
}
return -1;
}
public void Remove (TabPage value)
{
owner.Controls.Remove (value);
owner.Invalidate ();
}
public void RemoveAt (int index)
{
owner.Controls.RemoveAt (index);
owner.Invalidate ();
}
public virtual void RemoveByKey (string key)
{
int index = this.IndexOfKey (key);
if (index >= 0 && index < this.Count)
this.RemoveAt (index);
}
void ICollection.CopyTo (Array dest, int index)
{
owner.Controls.CopyTo (dest, index);
}
int IList.Add (object value)
{
TabPage page = value as TabPage;
if (value == null)
throw new ArgumentException ("value");
owner.Controls.Add (page);
return owner.Controls.IndexOf (page);
}
bool IList.Contains (object page)
{
TabPage tabPage = page as TabPage;
if (tabPage == null)
return false;
return Contains (tabPage);
}
int IList.IndexOf (object page)
{
TabPage tabPage = page as TabPage;
if (tabPage == null)
return -1;
return IndexOf (tabPage);
}
void IList.Insert (int index, object tabPage)
{
throw new NotSupportedException ();
}
public void Insert (int index, string text)
{
owner.InsertTab (index, new TabPage (text));
}
public void Insert (int index, TabPage tabPage)
{
owner.InsertTab (index, tabPage);
}
public void Insert (int index, string key, string text)
{
TabPage page = new TabPage(text);
page.Name = key;
owner.InsertTab (index, page);
}
public void Insert (int index, string key, string text, int imageIndex)
{
TabPage page = new TabPage(text);
page.Name = key;
owner.InsertTab (index, page);
page.ImageIndex = imageIndex;
}
public void Insert (int index, string key, string text, string imageKey)
{
TabPage page = new TabPage(text);
page.Name = key;
owner.InsertTab (index, page);
page.ImageKey = imageKey;
}
void IList.Remove (object value)
{
TabPage page = value as TabPage;
if (page == null)
return;
Remove ((TabPage) value);
}
}
#endregion // Class TabPage.TabPageCollection
}
}