using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace IP.Components
{
partial class Toolbox
{
/// <summary>
/// Represents a category in a <see cref="Toolbox"/> control.
/// </summary>
[Serializable]
[ToolboxItem(false)]
[DesignTimeVisible(false)]
[TypeConverter(typeof(TabConverter))]
public class Tab : IToolboxObject, ITab
{
#region Fields
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string _text;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private bool _opened;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private bool _visible = true;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private bool _selected;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private bool _allowDelete = true;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ItemCollection _items;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private TabCollection _tabs;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Point _location;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int _height;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private bool _renaming = false;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private ITab _owner;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private object _tag;
private static readonly Bitmap _collapsed;
private static readonly Bitmap _expanded;
private static readonly Bitmap _pointer;
private static readonly StringFormat _tabCaptionFormat;
private static readonly StringFormat _tabEmptyTextFormat;
/// <summary>
/// Represents the readonly Pointer <see cref="Item"/> of the <see cref="Tab"/>.
/// </summary>
public readonly Item PointerItem;
/// <summary>
/// Occurs when the <see cref="Tab"/> is opened or closed on the <see cref="Toolbox"/>.
/// </summary>
public event EventHandler<TabEventArgs> Toggle;
/// <summary>
/// Occurs when the <see cref="Tab"/> is selected/deselected on the <see cref="Toolbox"/>.
/// </summary>
public event EventHandler<TabEventArgs> SelectedChanged;
#endregion
#region Static constructor
[DebuggerHidden]
static Tab()
{
try
{
_collapsed = new Bitmap(Properties.Resources.Collapsed);
_collapsed.MakeTransparent(_collapsed.GetPixel(0, 0));
}
catch { }
try
{
_expanded = new Bitmap(Properties.Resources.Expanded);
_expanded.MakeTransparent(_expanded.GetPixel(0, 0));
}
catch { }
try
{
_pointer = new Bitmap(Properties.Resources.PointerBlack);
_pointer.MakeTransparent(_pointer.GetPixel(0, 0));
}
catch { }
_tabCaptionFormat = new StringFormat();
_tabCaptionFormat.FormatFlags = StringFormatFlags.NoWrap;
_tabCaptionFormat.Trimming = StringTrimming.EllipsisWord;
_tabEmptyTextFormat = new StringFormat();
_tabEmptyTextFormat.Alignment = StringAlignment.Center;
_tabEmptyTextFormat.LineAlignment = StringAlignment.Center;
}
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="Tab"/> class with the default values.
/// </summary>
public Tab() : this("")
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Tab"/> class with the specified category text.
/// </summary>
/// <param name="text">The text to display for the tab.</param>
public Tab(string text)
{
if (string.IsNullOrEmpty(text))
text = Properties.Resources.ToolboxTabDefaultName;
_text = text;
_items = new ItemCollection(this);
_tabs = new TabCollection(this);
PointerItem = CreatePointerItem(Properties.Resources.ToolboxPointerItem);
PointerItem.Owner = this;
PointerItem.Image = _pointer;
PointerItem.Enabled = false;
}
#endregion
#region Public Properties
/// <summary>
/// Gets the <see cref="Toolbox"/> object that contains the <see cref="Tab"/>.
/// </summary>
[Browsable(false)]
public Toolbox Toolbox
{
[DebuggerStepThrough]
get
{
ITab owner = this.Owner;
while (owner != null && !(owner is Toolbox))
{
owner = owner.Owner;
}
return (Toolbox)owner;
}
}
/// <summary>
/// Gets or sets the text to display for the <see cref="Tab"/>.
/// </summary>
public virtual string Text
{
[DebuggerStepThrough]
get { return _text; }
set
{
_text = value;
Toolbox toolbox = this.Toolbox;
if (toolbox != null)
{
toolbox.Invalidate(GetCaptionRectangle(false));
}
}
}
/// <summary>
/// Gets or sets the value indicating whether the <see cref="Tab"/> is opened on the <see cref="Toolbox"/>.
/// </summary>
[DefaultValue(false)]
public virtual bool Opened
{
[DebuggerStepThrough]
get { return _opened; }
set
{
if (_opened != value)
{
_opened = value;
OnToggleTab();
if (Owner != null)
Owner.Invalidate();
}
}
}
/// <summary>
/// Gets or sets the value indicating whether the <see cref="Tab"/> is visible on the <see cref="Toolbox"/>.
/// </summary>
[DefaultValue(true)]
public virtual bool Visible
{
[DebuggerStepThrough]
get { return _visible; }
set
{
if (_visible != value)
{
_visible = value;
if (Owner != null)
{
Owner.Invalidate();
}
}
}
}
/// <summary>
/// Indicates whether the <see cref="Tab"/> is currently selected on the <see cref="Toolbox"/>.
/// </summary>
[Browsable(false)]
[DefaultValue(false)]
public bool Selected
{
[DebuggerStepThrough]
get { return _selected; }
internal set
{
if (_selected != value)
{
Toolbox toolbox = this.Toolbox;
if (toolbox != null)
{
_selected = value;
Rectangle invalidate = GetCaptionRectangle(true);
invalidate.Inflate(1, 1);
toolbox.Invalidate(invalidate);
OnSelectedChanged();
}
}
}
}
/// <summary>
/// Gets or sets a value indicating whether the <see cref="Tab"/> is allowed to remove from the <see cref="Toolbox"/>.
/// </summary>
[DefaultValue(true)]
public bool AllowDelete
{
[DebuggerStepThrough]
get { return _allowDelete; }
[DebuggerStepThrough]
set
{
if (_allowDelete != value)
{
_allowDelete = value;
}
}
}
/// <summary>
/// Gets the location of the left top point where to draw the <see cref="Tab"/> on the <see cref="Toolbox"/>.
/// </summary>
[Browsable(false)]
public Point Location
{
[DebuggerStepThrough]
get { return _location; }
}
/// <summary>
/// Gets the bounds of the <see cref="Tab"/> on the <see cref="Toolbox"/>.
/// </summary>
[Browsable(false)]
public virtual Rectangle VisibleRectangle
{
get
{
Toolbox toolbox = this.Toolbox;
if (toolbox == null)
return Rectangle.Empty;
return new Rectangle(this.Location, new Size(this.Width, this.Height));
}
}
/// <summary>
/// Gets or sets an object that contains data to associate with the Tab.
/// </summary>
public object Tag
{
[DebuggerStepThrough]
get { return _tag; }
[DebuggerStepThrough]
set { _tag = value; }
}
#endregion
#region Other Properties
/// <summary>
/// Gets or sets the value indicating whether the <see cref="Tab"/> is currently renamed.
/// </summary>
protected internal bool Renaming
{
[DebuggerStepThrough]
get { return _renaming; }
set
{
Toolbox toolbox = this.Toolbox;
if (toolbox != null)
{
_renaming = value;
toolbox.Invalidate(GetCaptionRectangle(true));
}
}
}
#endregion
#region Public Methods
/// <summary>
/// Ensures that the <see cref="Tab"/> is visible within the <see cref="Toolbox"/>, scrolling the contents of the <see cref="Toolbox"/> if necessary.
/// </summary>
public void EnsureVisible()
{
Toolbox toolbox = this.Toolbox;
if (toolbox != null && Visible)
{
toolbox.EnsureVisible(VisibleRectangle);
}
}
/// <summary>
/// Selects the <see cref="Tab"/> on the <see cref="Toolbox"/>.
/// </summary>
public void Select()
{
Toolbox toolbox = this.Toolbox;
if (toolbox != null && Visible)
{
EnsureVisible();
toolbox.SelectTool(this);
}
}
/// <summary>
/// Sorts items contained in the <see cref="Tab"/> using the specified order.
/// </summary>
/// <param name="order">One of the <see cref="SortOrder"/> values indicating how to sort items.</param>
public void SortItems(SortOrder order)
{
if (order == SortOrder.None)
return;
Comparison<Item> compare = delegate(Item first, Item second)
{
if (first == second)
return 0;
if (order == SortOrder.Ascending)
return string.Compare(first.Text, second.Text);
else
return string.Compare(second.Text, first.Text);
};
Items.Sort(compare);
}
/// <summary>
/// Returns a string representation of the <see cref="Tab"/>.
/// </summary>
/// <returns>A string that states an <see cref="Tab"/> type and the its text.</returns>
public override string ToString()
{
return string.Format("{0}: {1}", GetType().Name, Text);
}
#endregion
#region Protected Methods
/// <summary>
/// Creates a Pointer <see cref="Item"/> for the <see cref="Tab"/>.
/// </summary>
/// <param name="text">The default text of the Pointer Item.</param>
/// <returns>An <see cref="Item"/> object representing the Pointer Item of the <see cref="Tab"/>.</returns>
protected virtual Item CreatePointerItem(string text)
{
return new Item(text);
}
/// <summary>
/// Notifies the <see cref="Toolbox"/> object that the state of the <see cref="Tab"/> is changed and invalidation is required.
/// </summary>
protected internal void NotifyInvalidate()
{
Toolbox toolbox = this.Toolbox;
if (toolbox != null && this.Opened && this.Visible)
toolbox.Invalidate(this.VisibleRectangle);
}
/// <summary>
/// Returns an object with information on which portion of a toolbox control is at a location specified by a <see cref="Point"/>.
/// </summary>
/// <param name="location">A <see cref="Point"/> containing the <see cref="Point.X"/> and <see cref="Point.Y"/> coordinates of the point to be hit tested.</param>
/// <returns>A <see cref="HitTestInfo"/> that contains information about the specified point on the <see cref="Toolbox"/>.</returns>
internal protected virtual HitTestInfo HitTest(Point location)
{
Toolbox toolbox = this.Toolbox;
if (toolbox == null)
return null;
Rectangle tabRect = this.VisibleRectangle;
Rectangle captionRect = this.GetCaptionRectangle(true);
HitTestInfo info = new HitTestInfo(location);
if (tabRect.Contains(location))
{
if (captionRect.Contains(location))
{
info.HitArea = HitArea.TabHeader;
}
else
{
if (toolbox.AllowNestedTabs)
{
foreach (Tab tab in Categories)
{
if ((toolbox.ShowAll || tab.Visible) && tab.VisibleRectangle.Contains(location))
{
return tab.HitTest(location);
}
}
}
if (toolbox.ShowPointer && (PointerItem.Visible || toolbox.ShowAll) && PointerItem.Bounds.Contains(location))
{
info.HitArea = HitArea.Item;
info.Tool = PointerItem;
}
else
{
foreach (Item item in this.Items)
{
if ((item.Visible || toolbox.ShowAll) && item.Bounds.Contains(location))
{
info.HitArea = HitArea.Item;
info.Tool = item;
break;
}
}
}
}
if (info.HitArea == HitArea.None)
info.HitArea = HitArea.TabBody;
if (info.Tool == null)
info.Tool = this;
}
return info;
}
/// <summary>
/// Returns the <see cref="GraphicsPath"/> structure that represents the <see cref="Tab"/> drawing region.
/// </summary>
protected virtual GraphicsPath GetTabPath()
{
Rectangle rect = GetCaptionRectangle(true);
GraphicsPath path = new GraphicsPath();
path.AddRectangle(rect);
return path;
}
/// <summary>
/// Draws the <see cref="Tab"/> on the <see cref="Toolbox"/>.
/// </summary>
/// <param name="e">A <see cref="PaintEventArgs"/> that contains the paint event data.</param>
protected virtual void OnPaint(PaintEventArgs e)
{
Toolbox toolbox = this.Toolbox;
if (toolbox == null)
return;
GraphicsPath tabPath = GetTabPath();
RectangleF tabRectangle = tabPath.GetBounds();
// Draw tab
if (Selected)
{
using (Brush selBrush = new SolidBrush(toolbox.TabSelectColor))
{
e.Graphics.FillPath(selBrush, tabPath);
}
using (Pen selPen = new Pen(toolbox.TabSelectBorderColor))
{
e.Graphics.DrawRectangle(selPen, tabRectangle.Left, tabRectangle.Top, tabRectangle.Width - 1, tabRectangle.Height - 1);
}
}
else if (toolbox.TabColorStyle != ColorStyle.None)
{
Color backColorStart;
Color backColorEnd;
switch (toolbox.TabColorStyle)
{
case ColorStyle.Lighter:
backColorStart = ControlPaint.Light(toolbox.BackColorGradientStart, 0.001f);
backColorEnd = ControlPaint.Light(toolbox.BackColorGradientEnd, 0.001f);
break;
case ColorStyle.Darker:
backColorStart = ControlPaint.Dark(toolbox.BackColorGradientStart, 0.001f);
backColorEnd = ControlPaint.Dark(toolbox.BackColorGradientEnd, 0.001f);
break;
default:
backColorStart = Color.LightGray;
backColorEnd = Color.Gray;
break;
}
RectangleF gradientRectangle = tabRectangle;
gradientRectangle.Inflate(1, 1);
using (Brush unselectedBrush = new LinearGradientBrush(gradientRectangle, backColorStart, backColorEnd, LinearGradientMode.Horizontal))
{
e.Graphics.FillPath(unselectedBrush, tabPath);
}
}
// Draw collapsed/expanded icon
Point stateIconPosition = Point.Round(tabRectangle.Location);
stateIconPosition.Y += (int)(tabRectangle.Height - Tab._collapsed.Height) / 2;
if (Opened)
{
e.Graphics.DrawImageUnscaled(Tab._expanded, stateIconPosition);
}
else
{
e.Graphics.DrawImageUnscaled(Tab._collapsed, stateIconPosition);
}
// Draw tab Text
Brush textBrush = new SolidBrush(toolbox.ForeColor);
SizeF textSize = e.Graphics.MeasureString(this.Text, toolbox.TabFont);
RectangleF textRectangle = new RectangleF(tabRectangle.Left + Tab._expanded.Width + Toolbox.Gap_IconFromText, tabRectangle.Top + (tabRectangle.Height - textSize.Height) / 2, tabRectangle.Width - Tab._expanded.Width - Toolbox.Gap_IconFromText, textSize.Height);
e.Graphics.DrawString(this.Text, toolbox.TabFont, textBrush, textRectangle, _tabCaptionFormat);
_height = (int)tabRectangle.Height;
// Draw items
if (Opened)
{
Point location = new Point((int)tabRectangle.Left + ((toolbox.DrawTabLevel) ? Toolbox.Gap_TabLevel : 0), (int)tabRectangle.Bottom);
if (Items.Count == 0 && (!toolbox.AllowNestedTabs || Categories.Count == 0) && (!toolbox.ShowAll || !toolbox.ShowPointer))
{
// Draw text ToolboxTabNoItemsText
// Before and after this text goes empty line with height = Toolbox.ItemHeight
string text = Properties.Resources.ToolboxTabNoItemsText;
textSize = e.Graphics.MeasureString(text, toolbox.Font, this.Width - ((toolbox.DrawTabLevel) ? Toolbox.Gap_TabLevel : 0));
textRectangle = new RectangleF(location.X, location.Y + Toolbox.Gap_ItemBetween + toolbox.ItemHeight, textSize.Width, textSize.Height);
e.Graphics.DrawString(text, toolbox.Font, textBrush, textRectangle, _tabEmptyTextFormat);
location.Offset(0, (int)(2 * toolbox.ItemHeight + 2 * Toolbox.Gap_ItemBetween + textSize.Height));
}
else
{
if (toolbox.AllowNestedTabs && this.Categories.Count > 0)
{
foreach (Tab tab in this.Categories)
{
if (tab.Visible || toolbox.ShowAll)
{
location.Offset(0, Toolbox.Gap_TabBetween);
tab.InternalPaint(e, ref location);
}
}
location.Offset(0, Toolbox.Gap_TabBetween);
}
if (toolbox.ShowPointer && (this.Items.Count > 0 || toolbox.ShowAll))
{
location.Offset(0, Toolbox.Gap_ItemBetween);
PointerItem.InternalPaint(e, location);
location.Offset(0, toolbox.ItemHeight);
}
foreach (Item item in Items)
{
if (item.Visible || toolbox.ShowAll)
{
location.Offset(0, Toolbox.Gap_ItemBetween);
item.InternalPaint(e, location);
location.Offset(0, toolbox.ItemHeight);
}
}
}
_height += (int)(location.Y - tabRectangle.Bottom);
if (toolbox.DrawTabLevel)
{
using (Pen levelPen = new Pen(Color.Black, 1))
{
e.Graphics.DrawLine(levelPen,
tabRectangle.Left + Toolbox.Gap_TabLevel / 3f,
tabRectangle.Bottom + Toolbox.Gap_TabBetween,
tabRectangle.Left + Toolbox.Gap_TabLevel / 3f,
location.Y - Toolbox.Gap_TabBetween);
e.Graphics.DrawLine(levelPen,
tabRectangle.Left + Toolbox.Gap_TabLevel / 3f,
location.Y - Toolbox.Gap_TabBetween,
tabRectangle.Left + Toolbox.Gap_TabLevel * 2 / 3f,
location.Y - Toolbox.Gap_TabBetween);
}
}
}
}
/// <summary>
/// Invoked when the mouse button is pressed on the <see cref="Tab"/>.
/// </summary>
/// <param name="e">A <see cref="System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
protected virtual void OnMouseDown(MouseEventArgs e)
{
}
/// <summary>
/// Invoked when the mouse button is depressed on the <see cref="Tab"/>.
/// </summary>
/// <param name="e">A <see cref="System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
/// <remarks>
/// If the mouse button is <see cref="MouseButtons.Left"/> and the mouse location is withing <see cref="Tab"/> caption, the <see cref="Tab"/> state is toggled.
/// <para/>If the mouse button is <see cref="MouseButtons.Right"/> the <see cref="IP.Components.Toolbox.TabMenu"/> is shown if available.
/// </remarks>
protected virtual void OnMouseUp(MouseEventArgs e)
{
Toolbox toolbox = this.Toolbox;
if (e.Button == MouseButtons.Left)
{
if (this.GetCaptionRectangle(true).Contains(e.Location))
{
this.Opened = !this.Opened;
toolbox.Invalidate();
}
}
else if (e.Button == MouseButtons.Right)
{
if (toolbox.TabMenu != null)
{
toolbox.TabMenu.Tag = this;
toolbox.TabMenu.Show(toolbox, e.Location);
}
}
}
/// <summary>
/// Invoked when the user clicks on the <see cref="Tab"/>.
/// </summary>
/// <param name="e">A <see cref="System.EventArgs"/> that contains the event data.</param>
protected virtual void OnClick(EventArgs e)
{
}
/// <summary>
/// Invoked when the user double clicks on the <see cref="Tab"/>.
/// </summary>
/// <param name="e">A <see cref="System.EventArgs"/> that contains the event data.</param>
protected virtual void OnDoubleClick(EventArgs e)
{
}
#region Event Fires
/// <summary>
/// Raises the <see cref="Toggle"/> event.
/// </summary>
protected virtual void OnToggleTab()
{
if (Toggle != null)
Toggle(this, new TabEventArgs(this));
}
/// <summary>
/// Raises the <see cref="SelectedChanged"/> event.
/// </summary>
protected virtual void OnSelectedChanged()
{
if (SelectedChanged != null)
SelectedChanged(this, new TabEventArgs(this));
}
#endregion
#endregion
#region Internal Methods
internal void InternalPaint(PaintEventArgs e, ref Point position)
{
this._location = position;
OnPaint(e);
position.Offset(0, this.Height);
}
internal void InternalMouseDown(MouseEventArgs e)
{
OnMouseDown(e);
}
internal void InternalMouseUp(MouseEventArgs e)
{
OnMouseUp(e);
}
internal void InternalClick(EventArgs e)
{
OnClick(e);
}
internal void InternalDoubleClick(EventArgs e)
{
OnDoubleClick(e);
}
/// <summary>
/// Calculates the height of the <see cref="Tab"/>.
/// </summary>
/// <param name="g">A drawing surface.</param>
/// <param name="visibleRect">A <see cref="Rectangle"/> representing the visible region of the <see cref="Toolbox"/>.</param>
internal protected virtual int CalculateTabHeight(Graphics g, Rectangle visibleRect)
{
Toolbox toolbox = this.Toolbox;
if (toolbox == null)
return 0;
int height = toolbox.TabHeight;
if (this.Opened)
{
if (toolbox.DrawTabLevel)
{
visibleRect.X += Toolbox.Gap_TabLevel;
visibleRect.Width -= Toolbox.Gap_TabLevel;
}
if (this.Items.Count == 0 && (!toolbox.AllowNestedTabs || this.Categories.Count == 0) && (!toolbox.ShowAll || !toolbox.ShowPointer))
{
height += 2 * toolbox.ItemHeight;
height += 2 * Toolbox.Gap_ItemBetween;
height += (int)g.MeasureString(Properties.Resources.ToolboxTabNoItemsText, toolbox.Font, visibleRect.Width).Height;
}
else
{
if (toolbox.AllowNestedTabs && this.Categories.Count > 0)
{
foreach (Tab tab in Categories)
{
height += tab.CalculateTabHeight(g, visibleRect);
height += Toolbox.Gap_TabBetween;
}
height += Toolbox.Gap_TabBetween;
}
if (toolbox.ShowPointer && (this.Items.Count > 0 || toolbox.ShowAll))
{
height += (toolbox.ItemHeight + Toolbox.Gap_ItemBetween);
}
foreach (Item item in Items)
{
if (item.Visible || toolbox.ShowAll)
{
height += (toolbox.ItemHeight + Toolbox.Gap_ItemBetween);
}
}
}
}
return height;
}
/// <summary>
/// Returns a <see cref="Rectangle"/> of the <see cref="Tab"/> caption.
/// </summary>
/// <param name="includeIcon">Indicates whether to include icon into returned rectangle.</param>
internal protected Rectangle GetCaptionRectangle(bool includeIcon)
{
Toolbox toolbox = this.Toolbox;
if (toolbox == null)
return Rectangle.Empty;
Rectangle caption = new Rectangle(this.Location, new Size(this.Width, toolbox.TabHeight));
if (!includeIcon)
{
int offset = Tab._collapsed.Width + Toolbox.Gap_IconFromText;
caption.Width -= offset;
caption.X += offset;
}
return caption;
}
#endregion
#region Private Methods
#endregion
#region ITab Members
/// <summary>
/// Invalidates the <see cref="Tab.VisibleRectangle">bounds</see> of the <see cref="Tab"/>.
/// </summary>
public void Invalidate()
{
ITab parent = Owner;
if (parent is Tab)
((Tab)parent).NotifyInvalidate();
else if (parent != null)
parent.Invalidate();
}
/// <summary>
/// Gets the width of the <see cref="Tab"/> on the <see cref="Toolbox"/>.
/// </summary>
[Browsable(false)]
public int Width
{
get
{
if (this.Owner == null)
return 0;
Toolbox toolbox = this.Toolbox;
if (toolbox == null)
return 0;
int width = this.Owner.Width;
if (this.Owner is Toolbox)
{
width = this.Owner.VisibleRectangle.Width - 2 * Toolbox.Gap_TabBorder;
}
else if (toolbox.DrawTabLevel)
{
width -= Toolbox.Gap_TabLevel;
}
return width;
}
}
/// <summary>
/// Gets the height of the <see cref="Tab"/> on the <see cref="Toolbox"/> taking into account whether the <see cref="Tab"/> is opened and including heights of all the visible items.
/// </summary>
[Browsable(false)]
public int Height
{
[DebuggerStepThrough]
get { return _height; }
}
/// <summary>
/// Gets the current (<see cref="Toolbox"/> or another <see cref="Tab"/>) object that contains the <see cref="Tab"/>.
/// </summary>
[Browsable(false)]
public ITab Owner
{
[DebuggerStepThrough]
get { return _owner; }
[DebuggerStepThrough]
internal set { _owner = value; }
}
/// <summary>
/// Gets the <see cref="ItemCollection">collection</see> of the items in the <see cref="Tab"/>.
/// </summary>
[MergableProperty(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public virtual ItemCollection Items
{
[DebuggerStepThrough]
get { return _items; }
}
/// <summary>
/// Gets the <see cref="TabCollection">collection</see> of the tabs in the <see cref="Tab"/>.
/// </summary>
[MergableProperty(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public virtual TabCollection Categories
{
[DebuggerStepThrough]
get { return _tabs; }
}
#endregion
}
}
}