Here's a complete subclass of the TabControl that has disabled tab page functionality built in. When you set one of the contained tab pages' Enabled property to False, the tab will render in a disabled font color and will not allow the user to open the tab. This version of the tab control handles the EnabledChanged event of any of its contained tab pages and redraws the tab appropriately. Add this class to your toolbox, drop it on a form, add a few tabs like normal. If you want to disable a tab simply set the Enabled property to false in your code:
MyTabControl.TabPage2.Enabled = False
Here's the class:
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
<ToolboxBitmap(GetType(TabControl))> _
Public Class BaseTabControl
Inherits System.Windows.Forms.TabControl
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Me.DrawMode = TabDrawMode.OwnerDrawFixed
End Sub
'BaseTabControl overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
'
End Sub
#End Region
#Region "--- Disabled Pages Functionality ---"
Private Const WM_LBUTTONDOWN As Integer = &H201
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_LBUTTONDOWN Then
Dim pt As New Point(m.LParam.ToInt32)
For i As Integer = 0 To Me.TabPages.Count - 1
If Me.GetTabRect(i).Contains(pt) Then
If Me.TabPages(i).Enabled Then
MyBase.WndProc(m)
End If
Exit For
End If
Next
Else
MyBase.WndProc(m)
End If
End Sub
Protected Overrides Sub OnKeyDown(ByVal ke As System.Windows.Forms.KeyEventArgs)
If Me.Focused Then
Dim selIndex As Integer = Me.SelectedIndex
If ke.KeyCode = Keys.Left AndAlso Not ke.Control AndAlso Not ke.Alt Then
For i As Integer = selIndex - 1 To 0 Step -1
If Me.TabPages(i).Enabled Then
Me.SelectedIndex = i
Exit For
End If
Next
ke.Handled = True
ElseIf ke.KeyCode = Keys.Right AndAlso Not ke.Control AndAlso Not ke.Alt Then
For i As Integer = selIndex + 1 To TabPages.Count - 1
If Me.TabPages(i).Enabled Then
Me.SelectedIndex = i
Exit For
End If
Next
ke.Handled = True
End If
End If
MyBase.OnKeyDown(ke)
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
Dim leftImgOffset, topImgOffset As Integer
Dim rBack As Rectangle
Dim rText As RectangleF
Dim img As Bitmap
Dim format As New StringFormat
Dim foreBrush As Brush
Dim backBrush As New SolidBrush(Me.TabPages(e.Index).BackColor)
If Me.TabPages(e.Index).Enabled Then
foreBrush = New SolidBrush(Me.TabPages(e.Index).ForeColor)
Else
foreBrush = New SolidBrush(SystemColors.ControlDark)
End If
If Me.TabPages(e.Index).ImageIndex <> -1 Then
img = CType(Me.ImageList.Images(Me.TabPages(e.Index).ImageIndex), Bitmap)
rText = New RectangleF(e.Bounds.X + (img.Width \ 2), e.Bounds.Y, _
e.Bounds.Width, e.Bounds.Height)
Else
rText = New RectangleF(e.Bounds.X, e.Bounds.Y, _
e.Bounds.Width, e.Bounds.Height)
End If
If e.State = DrawItemState.Selected Then
If e.Index = 0 Then
rBack = New Rectangle(e.Bounds.X + 4, e.Bounds.Y, _
e.Bounds.Width - 4, e.Bounds.Height)
Else
rBack = e.Bounds
End If
e.Graphics.FillRectangle(backBrush, rBack)
leftImgOffset = 6
topImgOffset = 5
Else
leftImgOffset = 2
topImgOffset = 2
End If
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(Me.TabPages(e.Index).Text, e.Font, foreBrush, rText, format)
If Me.TabPages(e.Index).ImageIndex <> -1 Then
Me.ImageList.Draw(e.Graphics, e.Bounds.X + leftImgOffset, _
e.Bounds.Top + topImgOffset, Me.TabPages(e.Index).ImageIndex)
End If
MyBase.OnDrawItem(e)
End Sub
Private Sub Tab_EnabledChanged(ByVal sender As Object, ByVal e As EventArgs)
If TypeOf sender Is TabPage Then
Me.Invalidate(Me.GetTabRect(DirectCast(sender, TabPage).TabIndex))
End If
End Sub
Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs)
If TypeOf e.Control Is TabPage Then
AddHandler e.Control.EnabledChanged, AddressOf Tab_EnabledChanged
End If
MyBase.OnControlAdded(e)
End Sub
Protected Overrides Sub OnControlRemoved(ByVal e As System.Windows.Forms.ControlEventArgs)
If TypeOf e.Control Is TabPage Then
RemoveHandler e.Control.EnabledChanged, AddressOf Tab_EnabledChanged
End If
MyBase.OnControlRemoved(e)
End Sub
#End Region
End Class
17 comments:
Excellent work!
Muy buen trabajo, justamente lo que andaba buscando, pero lastimosamente no me funcionó :(
Saludos
Very well done that man :)
This control is exactly what I need, but I can't get it to work. I was able to get te control added to my Toolbox and place it on a form, but whenever I try to debug, I get the following error.
Assembly 'D:\Visual Studio Projects\BaseTabControl\BaseTabControl\obj\ Debug\BaseTabControl.dll' doesn't contain any UserControl types.
Any ideas as to what I am doing wrong?
Thanks,
-jeremy
My problem ended up being that I had the BaseTabControl Class Library as the startup project. As soon as I set the windows application as the start up project the problem went away.
Works great so far. Too bad it only visibly disables the tabs when the DrawMode is set to OwnerDrawFixed. I sort of like the orange bars that shows up at the top of each tab when DrawMode is set to Normal. Not a big deal though. I'm still going to use it.
Thanks for posting this code, Beth. It has been extremely helpful to me. Nice work!
hi, i create component and added it to my form using tool box.
but i am not able to use this
BaseTabControl1.TabPage2.Enabled = False.
can you let me know what is correct code .
hi,
i have added component to my form after creating its dll file.
but i am not able to use following code its give me error.
BaseTabControl1.TabPage2.Enabled = False
can you let me know which is correct line of code???
hey thanks i got it working now.
BaseTabControl1.TabPages(1).Enabled = False
Cool....Tx dude. Its working for me.
I link wow gold and wow Power Leveling or wow gold
I have recently started using the blogengine.net and I having some problems here? in your blog you stated that we need to enable write permissions on the App_Data folder...unfortunately I don't understand how to enable it.
sexy lingerie manufacturer in china
I use a tabcontrol, style wizard. Almost all of my controls are on the shared tab control page and I use the other tabs to create some popup screens that can appear (with a click on a button or when hovering over an object) to enter some extra data. What I want is that whenever those screens appear the underlying controls must be blocked (set readonly). My problem I can't find a proper solution to block the controls of the Shared tab. Can you help me?
muscle building
I have a tabcontrol with 2 pages. OnLoad the 2nd Tabpage shall be disabled (grayed out and not selectable). Later with code I need to enable the 2nd tab. Any Ideas how this can be done? please.
I have a tabcontrol with 2 pages. OnLoad the 2nd Tabpage shall be disabled (grayed out and not selectable). Later with code I need to enable the 2nd tab. Any Ideas how this can be done? please.
wedding dresses
If the user has appropriate credentials, display the tab that was clicked. If the user does not have appropriate credentials, display a message box or some other user interface indicating that they do not have access, and return to the initial tab. coffee makers
Great thank you.
Post a Comment