TabControl重绘带关闭按钮和页选择

7 篇文章 0 订阅
7 篇文章 0 订阅

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
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值