'来源:http://www.vbforums.com/showthread.php?622242-TabControl-with-Close-button-on-TabPages-(with-Design-Time-support) Option Strict On Imports System.ComponentModel <ToolboxBitmap(GetType(System.Windows.Forms.TabControl))> Public Class TabControlEx Inherits System.Windows.Forms.TabControl Private Declare Auto Function SetParent Lib "user32" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr Protected CloseButtonCollection As New Dictionary(Of Button, TabPage) Private _ShowCloseButtonOnCurrentTab As Boolean = True Private _ShowCloseButtonOnTabs As Boolean = False <Browsable(True), DefaultValue(True), Category("Behavior"), Description("Indicates whether a close button should be shown on each TabPage")> Public Property ShowCloseButtonOnCurrentTab() As Boolean Get Return _ShowCloseButtonOnCurrentTab End Get Set(ByVal value As Boolean) _ShowCloseButtonOnCurrentTab = value For Each btn In CloseButtonCollection.Keys btn.Visible = _ShowCloseButtonOnCurrentTab Next RePositionCloseButtons() End Set End Property <Browsable(True), DefaultValue(True), Category("Behavior"), Description("Indicates whether a close button should be shown on each TabPage")> Public Property ShowCloseButtonOnTabs() As Boolean Get Return _ShowCloseButtonOnTabs End Get Set(ByVal value As Boolean) _ShowCloseButtonOnTabs = value RePositionCloseButtons() End Set End Property Protected Overrides Sub OnCreateControl() MyBase.OnCreateControl() For Each item In CloseButtonCollection item.Value.Text = item.Value.Text.Trim & Space(4) Next RePositionCloseButtons() End Sub Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs) MyBase.OnControlAdded(e) Dim tp As TabPage = DirectCast(e.Control, TabPage) Dim rect As Rectangle = Me.GetTabRect(Me.TabPages.IndexOf(tp)) Dim btn As Button = AddCloseButton(tp) btn.Size = New Size(rect.Height - 1, rect.Height - 1) btn.Location = New Point(rect.X + rect.Width - rect.Height - 1, rect.Y + 1) SetParent(btn.Handle, Me.Handle) AddHandler btn.Click, AddressOf OnCloseButtonClick CloseButtonCollection.Add(btn, tp) End Sub Protected Overrides Sub OnControlRemoved(ByVal e As System.Windows.Forms.ControlEventArgs) Dim btn As Button = CloseButtonOfTabPage(DirectCast(e.Control, TabPage)) RemoveHandler btn.Click, AddressOf OnCloseButtonClick CloseButtonCollection.Remove(btn) SetParent(btn.Handle, Nothing) btn.Dispose() MyBase.OnControlRemoved(e) End Sub Protected Overrides Sub OnLayout(ByVal levent As System.Windows.Forms.LayoutEventArgs) MyBase.OnLayout(levent) RePositionCloseButtons() End Sub Public Event CloseButtonClick As CancelEventHandler Protected Overridable Sub OnCloseButtonClick(ByVal sender As Object, ByVal e As EventArgs) If Not DesignMode Then Dim btn As Button = DirectCast(sender, Button) Dim tp As TabPage = CloseButtonCollection(btn) Dim ee As New CancelEventArgs RaiseEvent CloseButtonClick(sender, ee) If Not ee.Cancel Then If MsgBox("是否关闭 " + tp.Text.Trim + "标签?") = MsgBoxResult.Ok Then Me.TabPages.Remove(tp) RePositionCloseButtons() End If End If End If End Sub Protected Overridable Function AddCloseButton(ByVal tp As TabPage) As Button Dim closeButton As New Button With closeButton '' TODO: Give a good visual appearance to the Close button, maybe by assigning images etc. '' Here I have not used images to keep things simple. .Text = "X" .FlatStyle = FlatStyle.Flat .BackColor = Color.FromKnownColor(KnownColor.ButtonFace) .ForeColor = Color.White .Font = New Font("Microsoft Sans Serif", 6, FontStyle.Bold) End With Return closeButton End Function Public Sub RePositionCloseButtons() For Each item In CloseButtonCollection RePositionCloseButtons(item.Value) Next End Sub Public Sub RePositionCloseButtons(ByVal tp As TabPage) Dim btn As Button = CloseButtonOfTabPage(tp) If btn IsNot Nothing Then Dim tpIndex As Integer = Me.TabPages.IndexOf(tp) If tpIndex >= 0 Then Dim rect As Rectangle = Me.GetTabRect(tpIndex) If Me.SelectedTab Is tp Then btn.BackColor = Color.Red btn.Size = New Size(rect.Height - 1, rect.Height - 1) btn.Location = New Point(rect.X + rect.Width - rect.Height, rect.Y + 1) btn.Visible = ShowCloseButtonOnCurrentTab Else btn.BackColor = Color.FromKnownColor(KnownColor.ButtonFace) btn.Size = New Size(rect.Height - 3, rect.Height - 3) btn.Location = New Point(rect.X + rect.Width - rect.Height - 1, rect.Y + 1) btn.Visible = Me.ShowCloseButtonOnTabs End If btn.BringToFront() End If End If End Sub Protected Function CloseButtonOfTabPage(ByVal tp As TabPage) As Button Return (From item In CloseButtonCollection Where item.Value Is tp Select item.Key).FirstOrDefault End Function End Class