TabStrip:
[Designer(typeof(AsTabStripDesigner))]
[DefaultEvent("TabStripItemSelectionChanged")]
[DefaultProperty("Items")]
[ToolboxItem(true)]
[ToolboxBitmap("FATabStrip.bmp")]
public class AsTabStrip : BaseStyledPanel, ISupportInitialize, IDisposable {
#region 静态字段
internal static int PreferredWidth = 350;
internal static int PreferredHeight = 200;
#endregion
#region 常量
private const int DEF_HEADER_HEIGHT = 19;
private const int DEF_GLYPH_WIDTH = 40;
private int DEF_START_POS = 10;
#endregion
#region 事件
public event TabStripItemClosingHandler TabStripItemClosing;
public event TabStripItemChangedHandler TabStripItemSelectionChanged;
public event HandledEventHandler MenuItemsLoading;
public event EventHandler MenuItemsLoaded;
public event EventHandler TabStripItemClosed;
#endregion
#region 字段
private Rectangle stripButtonRect = Rectangle.Empty;
private AsTabStripItem selectedItem = null;
private ContextMenuStrip menu = null;
private AsTabStripMenuGlyph menuGlyph = null;
private AsTabStripCloseButton closeButton = null;
private AsTabStripItemCollection items;
private StringFormat sf = null;
private static Font defaultFont = new Font(" Tahoma", 8.25f, FontStyle.Regular);
private bool alwaysShowClose = true;
private bool isIniting = false;
private bool alwaysShowMenuGlyph = true;
private bool menuOpen = false;
#endregion
#region 方法
#region 公开方法
/// <summary>
/// 返回命中测试结果
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public HitTestResult HitTest(Point pt) {
if (closeButton.Bounds.Contains(pt))
return HitTestResult.CloseButton;
if (menuGlyph.Bounds.Contains(pt))
return HitTestResult.MenuGlyph;
if (GetTabItemByPoint(pt) != null)
return HitTestResult.TabItem;
// 没有其他的结果是可用的。
return HitTestResult.None;
}
/// <summary>
/// 添加一个<see cref="AsTabStripItem"/>到这个控件中而不选中
/// </summary>
/// <param name="tabItem"></param>
public void AddTab(AsTabStripItem tabItem) {
AddTab(tabItem, false);
}
/// <summary>
/// 添加一个<see cref="AsTabStripItem"/>到这个控件中
/// 设定前选定的项目。
/// </summary>
/// <param name="tabItem"></param>
public void AddTab(AsTabStripItem tabItem, bool autoSelect) {
tabItem.Dock = DockStyle.Fill;
Items.Add(tabItem);
if ((autoSelect && tabItem.Visible) || (tabItem.Visible && Items.DrawnCount < 1)) {
SelectedItem = tabItem;
SelectItem(tabItem);
}
}
/// <summary>
/// 从这个控件中移除一个<see cref="AsTabStripItem"/>
/// </summary>
/// <param name="tabItem"></param>
public void RemoveTab(AsTabStripItem tabItem) {
int tabIndex = Items.IndexOf(tabItem);
if (tabIndex >= 0) {
UnSelectItem(tabItem);
Items.Remove(tabItem);
}
if (Items.Count > 0) {
if (RightToLeft == RightToLeft.No) {
if (Items[tabIndex - 1] != null) {
SelectedItem = Items[tabIndex - 1];
} else {
SelectedItem = Items.FirstVisible;
}
} else {
if (Items[tabIndex + 1] != null) {
SelectedItem = Items[tabIndex + 1];
} else {
SelectedItem = Items.LastVisible;
}
}
}
}
/// <summary>
/// 获取或设置<see cref="AsTabStripItem"/>
/// 如果没有找到项目,返回空值。
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public AsTabStripItem GetTabItemByPoint(Point pt) {
AsTabStripItem item = null;
bool found = false;
for (int i = 0; i < Items.Count; i++) {
AsTabStripItem current = Items[i];
if (current.StripRect.Contains(pt) && current.Visible && current.IsDrawn) {
item = current;
found = true;
}
if (found)
break;
}
return item;
}
/// <summary>
/// 显示菜单
/// </summary>
public virtual void ShowMenu() {
if (menu.Visible == false && menu.Items.Count > 0) {
if (RightToLeft == RightToLeft.No) {
menu.Show(this, new Point(menuGlyph.Bounds.Left, menuGlyph.Bounds.Bottom));
} else {
menu.Show(this, new Point(menuGlyph.Bounds.Right, menuGlyph.Bounds.Bottom));
}
menuOpen = true;
}
}
#endregion
#region 内部方法
internal void UnDrawAll() {
for (int i = 0; i < Items.Count; i++) {
Items[i].IsDrawn = false;
}
}
internal void SelectItem(AsTabStripItem tabItem) {
tabItem.Dock = DockStyle.Fill;
tabItem.Visible = true;
tabItem.Selected = true;
}
internal void UnSelectItem(AsTabStripItem tabItem) {
//tabItem.Visible = false;
tabItem.Selected = false;
}
#endregion
#region 受保护方法
/// <summary>
/// 触发<see cref="TabStripItemClosing"/> 事件.
/// </summary>
/// <param name="e"></param>
protected internal virtual void OnTabStripItemClosing(TabStripItemClosingEventArgs e) {
if (TabStripItemClosing != null)
TabStripItemClosing(e);
}
/// <summary>
/// 触发 <see cref="TabStripItemClosed"/> 事件.
/// </summary>
/// <param name="e"></param>
protected internal virtual void OnTabStripItemClosed(EventArgs e) {
if (TabStripItemClosed != null)
TabStripItemClosed(this, e);
}
/// <summary>
/// 触发 <see cref="MenuItemsLoading"/> 事件.
/// </summary>
/// <param name="e"></param>
protected virtual void OnMenuItemsLoading(HandledEventArgs e) {
if (MenuItemsLoading != null)
MenuItemsLoading(this, e);
}
/// <summary>
/// 触发 <see cref="MenuItemsLoaded"/> 事件.
/// </summary>
/// <param name="e"></param>
protected virtual void OnMenuItemsLoaded(EventArgs e) {
if (MenuItemsLoaded != null)
MenuItemsLoaded(this, e);
}
/// <summary>
/// 触发 <see cref="TabStripItemSelectionChanged"/> 事件.
/// </summary>
/// <param name="e"></param>
protected virtual void OnTabStripItemChanged(TabStripItemChangedEventArgs e) {
if (TabStripItemSelectionChanged != null)
TabStripItemSelectionChanged(e);
}
/// <summary>
/// 加载 <see cref="AsTabStripItem"/>的菜单项
/// to this control.
/// </summary>
/// <param name="e"></param>
protected virtual void OnMenuItemsLoad(EventArgs e) {
menu.RightToLeft = RightToLeft;
menu.Items.Clear();
for (int i = 0; i < Items.Count; i++) {
AsTabStripItem item = Items[i];
if (!item.Visible)
continue;
ToolStripMenuItem tItem = new ToolStripMenuItem(item.Title);
tItem.Tag = item;
tItem.Image = item.Image;
menu.Items.Add(tItem);
}
OnMenuItemsLoaded(EventArgs.Empty);
}
#endregion
#region 重写方法
protected override void OnRightToLeftChanged(EventArgs e) {
base.OnRightToLeftChanged(e);
UpdateLayout();
Invalidate();
}
protected override void OnPaint(PaintEventArgs e) {
SetDefaultSelected();
Rectangle borderRc = ClientRectangle;
borderRc.Width--;
borderRc.Height--;
if (RightToLeft == RightToLeft.No) {
DEF_START_POS = 10;
} else {
DEF_START_POS = stripButtonRect.Right;
}
e.Graphics.DrawRectangle(SystemPens.ControlDark, borderRc);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
#region Draw Pages
for (int i = 0; i < Items.Count; i++) {
AsTabStripItem currentItem = Items[i];
if (!currentItem.Visible && !DesignMode)
continue;
OnCalcTabPage(e.Graphics, currentItem);
currentItem.IsDrawn = false;
if (!AllowDraw(currentItem))
continue;
OnDrawTabPage(e.Graphics, currentItem);
}
#endregion
#region 绘制线
if (RightToLeft == RightToLeft.No) {
if (Items.DrawnCount == 0 || Items.VisibleCount == 0) {
e.Graphics.DrawLine(SystemPens.ControlDark, new Point(0, DEF_HEADER_HEIGHT),
new Point(ClientRectangle.Width, DEF_HEADER_HEIGHT));
} else if (SelectedItem != null && SelectedItem.IsDrawn) {
Point end = new Point((int)SelectedItem.StripRect.Left - 9, DEF_HEADER_HEIGHT);
e.Graphics.DrawLine(SystemPens.ControlDark, new Point(0, DEF_HEADER_HEIGHT), end);
end.X += (int)SelectedItem.StripRect.Width + 10;
e.Graphics.DrawLine(SystemPens.ControlDark, end, new Point(ClientRectangle.Width, DEF_HEADER_HEIGHT));
}
} else {
if (Items.DrawnCount == 0 || Items.VisibleCount == 0) {
e.Graphics.DrawLine(SystemPens.ControlDark, new Point(0, DEF_HEADER_HEIGHT),
new Point(ClientRectangle.Width, DEF_HEADER_HEIGHT));
} else if (SelectedItem != null && SelectedItem.IsDrawn) {
Point end = new Point((int)SelectedItem.StripRect.Left, DEF_HEADER_HEIGHT);
e.Graphics.DrawLine(SystemPens.ControlDark, new Point(0, DEF_HEADER_HEIGHT), end);
end.X += (int)SelectedItem.StripRect.Width + 20;
e.Graphics.DrawLine(SystemPens.ControlDark, end, new Point(ClientRectangle.Width, DEF_HEADER_HEIGHT));
}
}
#endregion
#region 绘制下拉菜单和关闭符号
if (AlwaysShowMenuGlyph || Items.DrawnCount > Items.VisibleCount)
menuGlyph.DrawGlyph(e.Graphics);
if (AlwaysShowClose || (SelectedItem != null && SelectedItem.CanClose))
closeButton.DrawCross(e.Graphics);
#endregion
}
protected override void OnMouseDown(MouseEventArgs e) {
base.OnMouseDown(e);
if (e.Button != MouseButtons.Left)
return;
HitTestResult result = HitTest(e.Location);
if (result == HitTestResult.MenuGlyph) {
HandledEventArgs args = new HandledEventArgs(false);
OnMenuItemsLoading(args);
if (!args.Handled)
OnMenuItemsLoad(EventArgs.Empty);
ShowMenu();
} else if (result == HitTestResult.CloseButton) {
if (SelectedItem != null) {
TabStripItemClosingEventArgs args = new TabStripItemClosingEventArgs(SelectedItem);
OnTabStripItemClosing(args);
if (!args.Cancel && SelectedItem.CanClose) {
RemoveTab(SelectedItem);
OnTabStripItemClosed(EventArgs.Empty);
}
}
} else if (result == HitTestResult.TabItem) {
AsTabStripItem item = GetTabItemByPoint(e.Location);
if (item != null)
SelectedItem = item;
}
Invalidate();
}
protected override void OnMouseMove(MouseEventArgs e) {
base.OnMouseMove(e);
if (menuGlyph.Bounds.Contains(e.Location)) {
menuGlyph.IsMouseOver = true;
Invalidate(menuGlyph.Bounds);
} else {
if (menuGlyph.IsMouseOver && !menuOpen) {
menuGlyph.IsMouseOver = false;
Invalidate(menuGlyph.Bounds);
}
}
if (closeButton.Bounds.Contains(e.Location)) {
closeButton.IsMouseOver = true;
Invalidate(closeButton.Bounds);
} else {
if (closeButton.IsMouseOver) {
closeButton.IsMouseOver = false;
Invalidate(closeButton.Bounds);
}
}
}
protected override void OnMouseLeave(EventArgs e) {
base.OnMouseLeave(e);
menuGlyph.IsMouseOver = false;
Invalidate(menuGlyph.Bounds);
closeButton.IsMouseOver = false;
Invalidate(closeButton.Bounds);
}
protected override void OnSizeChanged(EventArgs e) {
base.OnSizeChanged(e);
if (isIniting)
return;
UpdateLayout();
}
#endregion
#region 私有方法
private bool AllowDraw(AsTabStripItem item) {
bool result = true;
if (RightToLeft == RightToLeft.No) {
if (item.StripRect.Right >= stripButtonRect.Width)
result = false;
} else {
if (item.StripRect.Left <= stripButtonRect.Left)
return false;
}
return result;
}
private void SetDefaultSelected() {
if (selectedItem == null && Items.Count > 0)
SelectedItem = Items[0];
for (int i = 0; i < Items.Count; i++) {
AsTabStripItem itm = Items[i];
itm.Dock = DockStyle.Fill;
}
}
private void OnMenuItemClicked(object sender, ToolStripItemClickedEventArgs e) {
AsTabStripItem clickedItem = (AsTabStripItem)e.ClickedItem.Tag;
SelectedItem = clickedItem;
}
private void OnMenuVisibleChanged(object sender, EventArgs e) {
if (menu.Visible == false) {
menuOpen = false;
}
}
private void OnCalcTabPage(Graphics g, AsTabStripItem currentItem) {
Font currentFont = Font;
if (currentItem == SelectedItem)
currentFont = new Font(Font, FontStyle.Bold);
SizeF textSize = g.MeasureString(currentItem.Title, currentFont, new SizeF(200, 10), sf);
textSize.Width += 20;
if (RightToLeft == RightToLeft.No) {
RectangleF buttonRect = new RectangleF(DEF_START_POS, 3, textSize.Width, 17);
currentItem.StripRect = buttonRect;
DEF_START_POS += (int)textSize.Width;
} else {
RectangleF buttonRect = new RectangleF(DEF_START_POS - textSize.Width + 1, 3, textSize.Width - 1, 17);
currentItem.StripRect = buttonRect;
DEF_START_POS -= (int)textSize.Width;
}
}
private void OnDrawTabPage(Graphics g, AsTabStripItem currentItem) {
bool isFirstTab = Items.IndexOf(currentItem) == 0;
Font currentFont = Font;
if (currentItem == SelectedItem)
currentFont = new Font(Font, FontStyle.Bold);
SizeF textSize = g.MeasureString(currentItem.Title, currentFont, new SizeF(200, 10), sf);
textSize.Width += 20;
RectangleF buttonRect = currentItem.StripRect;
GraphicsPath path = new GraphicsPath();
LinearGradientBrush brush;
int mtop = 3;
#region 绘制从右至左
if (RightToLeft == RightToLeft.No) {
if (currentItem == SelectedItem || isFirstTab) {
path.AddLine(buttonRect.Left - 10, buttonRect.Bottom - 1,
buttonRect.Left + (buttonRect.Height / 2) - 4, mtop + 4);
} else {
path.AddLine(buttonRect.Left, buttonRect.Bottom - 1, buttonRect.Left,
buttonRect.Bottom - (buttonRect.Height / 2) - 2);
path.AddLine(buttonRect.Left, buttonRect.Bottom - (buttonRect.Height / 2) - 3,
buttonRect.Left + (buttonRect.Height / 2) - 4, mtop + 3);
}
path.AddLine(buttonRect.Left + (buttonRect.Height / 2) + 2, mtop, buttonRect.Right - 3, mtop);
path.AddLine(buttonRect.Right, mtop + 2, buttonRect.Right, buttonRect.Bottom - 1);
path.AddLine(buttonRect.Right - 4, buttonRect.Bottom - 1, buttonRect.Left, buttonRect.Bottom - 1);
path.CloseFigure();
if (currentItem == SelectedItem) {
brush = new LinearGradientBrush(buttonRect, SystemColors.ControlLightLight, SystemColors.Window, LinearGradientMode.Vertical);
} else {
brush = new LinearGradientBrush(buttonRect, SystemColors.ControlLightLight, SystemColors.Control, LinearGradientMode.Vertical);
}
g.FillPath(brush, path);
g.DrawPath(SystemPens.ControlDark, path);
if (currentItem == SelectedItem) {
g.DrawLine(new Pen(brush), buttonRect.Left - 9, buttonRect.Height + 2,
buttonRect.Left + buttonRect.Width - 1, buttonRect.Height + 2);
}
PointF textLoc = new PointF(buttonRect.Left + buttonRect.Height - 4, buttonRect.Top + (buttonRect.Height / 2) - (textSize.Height / 2) - 3);
RectangleF textRect = buttonRect;
textRect.Location = textLoc;
textRect.Width = buttonRect.Width - (textRect.Left - buttonRect.Left) - 4;
textRect.Height = textSize.Height + currentFont.Size / 2;
if (currentItem == SelectedItem) {
//textRect.Y -= 2;
g.DrawString(currentItem.Title, currentFont, new SolidBrush(ForeColor), textRect, sf);
} else {
g.DrawString(currentItem.Title, currentFont, new SolidBrush(ForeColor), textRect, sf);
}
}
#endregion
#region 绘制从右至左
if (RightToLeft == RightToLeft.Yes) {
if (currentItem == SelectedItem || isFirstTab) {
path.AddLine(buttonRect.Right + 10, buttonRect.Bottom - 1,
buttonRect.Right - (buttonRect.Height / 2) + 4, mtop + 4);
} else {
path.AddLine(buttonRect.Right, buttonRect.Bottom - 1, buttonRect.Right,
buttonRect.Bottom - (buttonRect.Height / 2) - 2);
path.AddLine(buttonRect.Right, buttonRect.Bottom - (buttonRect.Height / 2) - 3,
buttonRect.Right - (buttonRect.Height / 2) + 4, mtop + 3);
}
path.AddLine(buttonRect.Right - (buttonRect.Height / 2) - 2, mtop, buttonRect.Left + 3, mtop);
path.AddLine(buttonRect.Left, mtop + 2, buttonRect.Left, buttonRect.Bottom - 1);
path.AddLine(buttonRect.Left + 4, buttonRect.Bottom - 1, buttonRect.Right, buttonRect.Bottom - 1);
path.CloseFigure();
if (currentItem == SelectedItem) {
brush =
new LinearGradientBrush(buttonRect, SystemColors.ControlLightLight, SystemColors.Window,
LinearGradientMode.Vertical);
} else {
brush =
new LinearGradientBrush(buttonRect, SystemColors.ControlLightLight, SystemColors.Control,
LinearGradientMode.Vertical);
}
g.FillPath(brush, path);
g.DrawPath(SystemPens.ControlDark, path);
if (currentItem == SelectedItem) {
g.DrawLine(new Pen(brush), buttonRect.Right + 9, buttonRect.Height + 2,
buttonRect.Right - buttonRect.Width + 1, buttonRect.Height + 2);
}
PointF textLoc = new PointF(buttonRect.Left + 2, buttonRect.Top + (buttonRect.Height / 2) - (textSize.Height / 2) - 2);
RectangleF textRect = buttonRect;
textRect.Location = textLoc;
textRect.Width = buttonRect.Width - (textRect.Left - buttonRect.Left) - 10;
textRect.Height = textSize.Height + currentFont.Size / 2;
if (currentItem == SelectedItem) {
textRect.Y -= 1;
g.DrawString(currentItem.Title, currentFont, new SolidBrush(ForeColor), textRect, sf);
} else {
g.DrawString(currentItem.Title, currentFont, new SolidBrush(ForeColor), textRect, sf);
}
//g.FillRectangle(Brushes.Red, textRect);
}
#endregion
currentItem.IsDrawn = true;
}
private void UpdateLayout() {
if (RightToLeft == RightToLeft.No) {
sf.Trimming = StringTrimming.EllipsisCharacter;
sf.FormatFlags |= StringFormatFlags.NoWrap;
sf.FormatFlags &= StringFormatFlags.DirectionRightToLeft;
stripButtonRect = new Rectangle(0, 0, ClientSize.Width - DEF_GLYPH_WIDTH - 2, 10);
menuGlyph.Bounds = new Rectangle(ClientSize.Width - DEF_GLYPH_WIDTH, 2, 16, 16);
closeButton.Bounds = new Rectangle(ClientSize.Width - 20, 2, 16, 16);
} else {
sf.Trimming = StringTrimming.EllipsisCharacter;
sf.FormatFlags |= StringFormatFlags.NoWrap;
sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
stripButtonRect = new Rectangle(DEF_GLYPH_WIDTH + 2, 0, ClientSize.Width - DEF_GLYPH_WIDTH - 15, 10);
closeButton.Bounds = new Rectangle(4, 2, 16, 16); //ClientSize.Width - DEF_GLYPH_WIDTH, 2, 16, 16);
menuGlyph.Bounds = new Rectangle(20 + 4, 2, 16, 16); //this.ClientSize.Width - 20, 2, 16, 16);
}
DockPadding.Top = DEF_HEADER_HEIGHT + 1;
DockPadding.Bottom = 1;
DockPadding.Right = 1;
DockPadding.Left = 1;
}
private void OnCollectionChanged(object sender, CollectionChangeEventArgs e) {
AsTabStripItem itm = (AsTabStripItem)e.Element;
if (e.Action == CollectionChangeAction.Add) {
Controls.Add(itm);
OnTabStripItemChanged(new TabStripItemChangedEventArgs(itm, FATabStripItemChangeTypes.Added));
} else if (e.Action == CollectionChangeAction.Remove) {
Controls.Remove(itm);
OnTabStripItemChanged(new TabStripItemChangedEventArgs(itm, FATabStripItemChangeTypes.Removed));
} else {
OnTabStripItemChanged(new TabStripItemChangedEventArgs(itm, FATabStripItemChangeTypes.Changed));
}
UpdateLayout();
Invalidate();
}
#endregion
#endregion
#region 构造函数
public AsTabStrip() {
BeginInit();
SetStyle(ControlStyles.ContainerControl, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.Selectable, true);
items = new AsTabStripItemCollection();
items.CollectionChanged += new CollectionChangeEventHandler(OnCollectionChanged);
base.Size = new Size(350, 200);
menu = new ContextMenuStrip();
menu.Renderer = ToolStripRenderer;
menu.ItemClicked += new ToolStripItemClickedEventHandler(OnMenuItemClicked);
menu.VisibleChanged += new EventHandler(OnMenuVisibleChanged);
menuGlyph = new AsTabStripMenuGlyph(ToolStripRenderer);
closeButton = new AsTabStripCloseButton(ToolStripRenderer);
Font = defaultFont;
sf = new StringFormat();
EndInit();
UpdateLayout();
}
#endregion
#region 属性
[DefaultValue(null)]
[RefreshProperties(RefreshProperties.All)]
public AsTabStripItem SelectedItem {
get { return selectedItem; }
set {
if (selectedItem == value)
return;
if (value == null && Items.Count > 0) {
AsTabStripItem itm = Items[0];
if (itm.Visible) {
selectedItem = itm;
selectedItem.Selected = true;
selectedItem.Dock = DockStyle.Fill;
}
} else {
selectedItem = value;
}
foreach (AsTabStripItem itm in Items) {
if (itm == selectedItem) {
SelectItem(itm);
itm.Dock = DockStyle.Fill;
itm.Show();
} else {
UnSelectItem(itm);
itm.Hide();
}
}
SelectItem(selectedItem);
Invalidate();
if (!selectedItem.IsDrawn) {
Items.MoveTo(0, selectedItem);
Invalidate();
}
OnTabStripItemChanged(
new TabStripItemChangedEventArgs(selectedItem, FATabStripItemChangeTypes.SelectionChanged));
}
}
[DefaultValue(true)]
public bool AlwaysShowMenuGlyph {
get { return alwaysShowMenuGlyph; }
set {
if (alwaysShowMenuGlyph == value)
return;
alwaysShowMenuGlyph = value;
Invalidate();
}
}
[DefaultValue(true)]
public bool AlwaysShowClose {
get { return alwaysShowClose; }
set {
if (alwaysShowClose == value)
return;
alwaysShowClose = value;
Invalidate();
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public AsTabStripItemCollection Items {
get { return items; }
}
[DefaultValue(typeof(Size), "350, 200")]
public new Size Size {
get { return base.Size; }
set {
if (base.Size == value)
return;
base.Size = value;
UpdateLayout();
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new ControlCollection Controls {
get { return base.Controls; }
}
#endregion
#region 可序列化
public bool ShouldSerializeFont() {
return Font != null && !Font.Equals(defaultFont);
}
public bool ShouldSerializeSelectedItem() {
return true;
}
public bool ShouldSerializeItems() {
return items.Count > 0;
}
public new void ResetFont() {
Font = defaultFont;
}
#endregion
#region ISupportInitialize Members
public void BeginInit() {
isIniting = true;
}
public void EndInit() {
isIniting = false;
}
#endregion
#region 释放资源
/// <summary>
/// 执行应用定义的任务与释放,释放非托管资源,或复位。
/// </summary>
/// <filterpriority>2</filterpriority>
protected override void Dispose(bool disposing) {
if (disposing) {
items.CollectionChanged -= new CollectionChangeEventHandler(OnCollectionChanged);
menu.ItemClicked -= new ToolStripItemClickedEventHandler(OnMenuItemClicked);
menu.VisibleChanged -= new EventHandler(OnMenuVisibleChanged);
foreach (AsTabStripItem item in items) {
if (item != null && !item.IsDisposed)
item.Dispose();
}
if (menu != null && !menu.IsDisposed)
menu.Dispose();
if (sf != null)
sf.Dispose();
}
base.Dispose(disposing);
}
#endregion
}
AsTabStripItem:
[Designer(typeof(AsTabStripItemDesigner))]
[ToolboxItem(false)]
[DefaultProperty("Title")]
[DefaultEvent("Changed")]
public class AsTabStripItem : Panel {
#region 事件
public event EventHandler Changed;
#endregion
#region 字段
//private DrawItemState drawState = DrawItemState.None;
private RectangleF stripRect = Rectangle.Empty;
private Image image = null;
private bool canClose = true;
private bool selected = false;
private bool visible = true;
private bool isDrawn = false;
private string title = string.Empty;
#endregion
#region 属性
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new Size Size {
get { return base.Size; }
set { base.Size = value; }
}
[DefaultValue(true)]
public new bool Visible {
get { return visible; }
set {
if (visible == value)
return;
visible = value;
OnChanged();
}
}
internal RectangleF StripRect {
get { return stripRect; }
set { stripRect = value; }
}
[Browsable(false)]
[DefaultValue(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsDrawn {
get { return isDrawn; }
set {
if (isDrawn == value)
return;
isDrawn = value;
}
}
/// <summary>;
/// 显示<see cref="AsTabStripItem"/>;图片菜单项。
/// </summary>;
[DefaultValue(null)]
public Image Image {
get { return image; }
set { image = value; }
}
[DefaultValue(true)]
public bool CanClose {
get { return canClose; }
set { canClose = value; }
}
[DefaultValue("Name")]
public string Title {
get {
return title;
}
set {
if (title == value)
return;
title = value;
OnChanged();
}
}
/// <summary>;
/// 获取并设置一个值,该值指示是否选择了页面。
/// </summary>;
[DefaultValue(false)]
[Browsable(false)]
public bool Selected {
get { return selected; }
set {
if (selected == value)
return;
selected = value;
}
}
[Browsable(false)]
public string Caption {
get { return Title; }
}
#endregion
#region 构造函数
public AsTabStripItem() : this(string.Empty, null) {
}
public AsTabStripItem(Control displayControl) : this(string.Empty, displayControl) {
}
public AsTabStripItem(string caption, Control displayControl) {
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ContainerControl, true);
selected = false;
Visible = true;
UpdateText(caption, displayControl);
//添加一个控件
if (displayControl != null)
Controls.Add(displayControl);
}
#endregion
#region 释放资源
/// <summary>;
/// 正确配置的交易损失控制页
/// </summary>;
/// <param name="disposing">;</param>;
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
if (disposing) {
if (image != null)
image.Dispose();
}
}
#endregion
#region 可序列化
public bool ShouldSerializeIsDrawn() {
return false;
}
public bool ShouldSerializeDock() {
return false;
}
public bool ShouldSerializeControls() {
return Controls != null && Controls.Count & gt; 0;
}
public bool ShouldSerializeVisible() {
return true;
}
#endregion
#region 方法
private void UpdateText(string caption, Control displayControl) {
if (displayControl != null && displayControl is ICaptionSupport) {
ICaptionSupport capControl = displayControl as ICaptionSupport;
Title = capControl.Caption;
} else if (caption.Length <= 0 && displayControl != null) {
Title = displayControl.Text;
} else if (caption != null) {
Title = caption;
} else {
Title = string.Empty;
}
}
public void Assign(AsTabStripItem item) {
Visible = item.Visible;
Text = item.Text;
CanClose = item.CanClose;
Tag = item.Tag;
}
protected internal virtual void OnChanged() {
if (Changed != null)
Changed(this, EventArgs.Empty);
}
/// <summary>;
/// 返回页面的字符串表示。
/// </summary>;
/// <returns>;</returns>;
public override string ToString() {
return Caption;
}
#endregion
}
BaseStyledPanel:
public partial class BaseStyledPanel : ContainerControl {
#region 字段
private static ToolStripProfessionalRenderer renderer;
#endregion
#region 事件
public event EventHandler ThemeChanged;
#endregion
#region 构造函数
static BaseStyledPanel() {
renderer = new ToolStripProfessionalRenderer();
}
public BaseStyledPanel() {
// Set painting style for better performance.
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
}
#endregion
#region 方法
protected override void OnSystemColorsChanged(EventArgs e) {
base.OnSystemColorsChanged(e);
UpdateRenderer();
Invalidate();
}
protected virtual void OnThemeChanged(EventArgs e) {
if (ThemeChanged != null)
ThemeChanged(this, e);
}
private void UpdateRenderer() {
if (!UseThemes) {
renderer.ColorTable.UseSystemColors = true;
} else {
renderer.ColorTable.UseSystemColors = false;
}
}
#endregion
#region 属性
[Browsable(false)]
public ToolStripProfessionalRenderer ToolStripRenderer {
get { return renderer; }
}
[DefaultValue(true)]
[Browsable(false)]
public bool UseThemes {
get {
return VisualStyleRenderer.IsSupported && VisualStyleInformation.IsSupportedByOS && Application.RenderWithVisualStyles;
}
}
#endregion
}
文章评论