Friday, July 3, 2009

Custom drawn Close button in TabControl

We may want to close the tab pages by clicking on Close sign.

The Tab Control does not provide built in functionality to accomplish this.

We need to draw Custom Image(Close Sign) on the tab pages and need to handle the clicking of close Sign.

The following code explains how to draw the image on the right hand side of tab pages and while clicking on the Close symbol the corresponding pages will be closed.

This is accomplished by OnDrawItem Event and MouseClickEvent of TabControl.


We need 16 x 16 Close Image. (I herewith attached an image).

Add TabControl to the Form.

Then Add the below Coding in the Code Behind Section.

For your convenience I have provided the code in VB.Net and C#.


VB Code



Public Class Form1

Dim _imgHitArea As Point = New Point(13, 2)
Dim _imageLocation As Point = New Point(15, 5)

Public Sub New()
InitializeComponent()

'Set the Mode of Drawing as Owner Drawn
TabControl1.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed

'Add the Handler to draw the Image on Tab Pages
AddHandler TabControl1.DrawItem, AddressOf TabControl1_DrawItem
End Sub

Private Sub TabControl1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)
Try
'Close Image to draw
Dim img As Image = New Bitmap("C:\Close.gif")
Dim r As Rectangle = e.Bounds

r = Me.TabControl1.GetTabRect(e.Index)
r.Offset(2, 2)
Dim TitleBrush As Brush = New SolidBrush(Color.Black)
Dim f As Font = Me.Font
Dim title As String = Me.TabControl1.TabPages(e.Index).Text
e.Graphics.DrawString(title, f, TitleBrush, New PointF(r.X, r.Y))
e.Graphics.DrawImage(img, New Point(r.X + (Me.TabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y))

Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub

Private Sub TabControl1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TabControl1.MouseClick
Dim tc As TabControl = CType(sender, TabControl)
Dim p As Point = e.Location
Dim _tabWidth As Integer

_tabWidth = Me.TabControl1.GetTabRect(tc.SelectedIndex).Width - (_imgHitArea.X)
Dim r As Rectangle = Me.TabControl1.GetTabRect(tc.SelectedIndex)
r.Offset(_tabWidth, _imgHitArea.Y)
r.Width = 16
r.Height = 16
If r.Contains(p) Then
Dim TabP As TabPage = DirectCast(tc.TabPages.Item(tc.SelectedIndex), TabPage)
tc.TabPages.Remove(TabP)
End If
End Sub


End Class

[/CODE]


C# Code

[CODE]

public partial class Form1 : Form
{
private Point _imageLocation = new Point(15, 5);
private Point _imgHitArea = new Point(13, 2);

public Form1()
{
InitializeComponent();

//Set the Mode of Drawing as Owner Drawn
this.tabControl1.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;

//Add the Handler to draw the Image on Tab Pages
tabControl1.DrawItem += TabControl1_DrawItem;
}

private void TabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
try
{
//Close Image to draw
Image img = new Bitmap("C:\\Close.gif");

Rectangle r = e.Bounds;
r = this.tabControl1.GetTabRect(e.Index);
r.Offset(2, 2);

Brush TitleBrush = new SolidBrush(Color.Black);
Font f = this.Font;

string title = this.tabControl1.TabPages[e.Index].Text;

e.Graphics.DrawString(title, f, TitleBrush, new PointF(r.X, r.Y));
e.Graphics.DrawImage(Img, new Point(r.X + (this.tabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));
}
catch (Exception) { }


}

private void TabControl1_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
TabControl tc = (TabControl)sender;
Point p = e.Location;
int _tabWidth = 0;
_tabWidth = this.tabControl1.GetTabRect(tc.SelectedIndex).Width - (_imgHitArea.X);
Rectangle r = this.tabControl1.GetTabRect(tc.SelectedIndex);
r.Offset(_tabWidth, _imgHitArea.Y);
r.Width = 16;
r.Height = 16;
if (r.Contains(p)) {
TabPage TabP = (TabPage)tc.TabPages[tc.SelectedIndex];
tc.TabPages.Remove(TabP);
}
}



}

1 comment: