[RESOLVED] Tab pages backcolor & flicker
Hi Guys,
I have an program which uses an MDI Form. My mdi form's background is painted gradient through a code I use.
Now I need to use tab pages in my Mdi Form. But I want to see the background of my MDI (which is coloured). I tried but failed so I decided to colour the background of tab pages to that mdi. I am able to paint it gradient so that part is okay. But there are two problems :
- A lot of flickering takes place in my tab pages color whenever I resize my mdi form or perform some activity (like insert child form or so).
- the area around tab headers is not coloured and shows dark grey. How to fix that ?
My Mdi form when painted gradient works okay and has minimum flicker. But now I have put a tab control docked to fill. Though I am able to pain area of page to gradient but there is a lot of flickering.
If anyone can advice how to solve the problem, I will be thankful.
http://img34.imageshack.us/img34/2234/mditab.th.png
Code:
Private Sub TabPage1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles TabPage1.Paint
Dim g As Graphics = TabPage1.CreateGraphics
Dim rect As New Rectangle(0, 0, TabPage1.Width, TabPage1.Height)
Dim b As New System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.FromArgb(0, 58, 140), Color.FromArgb(0, 215, 255), Drawing2D.LinearGradientMode.Vertical) ' Or Drawing2D.LinearGradientMode.ForwardDiagonal)
g.FillRectangle(b, rect)
' g.Dispose()
End Sub
Thanks,
Cheers,
GR
Re: Tab pages backcolor & flicker
Hi,
This code is taken from an old project and should allow you to colour the area next to the TabHeaders:
(nb: Try the code in the Paint event. If you need to use the DrawItem Event you might need to set the TabControls DrawMode property to OwnerDrawFixed
If thats the case you will need to manually paint the TabHeaders and their text.)
VB Code:
'Colour in the area surrounding the Tab Headers (if you are using MultiLine Tabs, you will need to tweak this)
Private Sub TabControl1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles TabControl1.DrawItem
Dim Rect1 As Rectangle = TabControl1.Bounds 'Get the TabControl's rectangle
Dim Rect2 As New Rectangle
'Record the Left(X), Top(Y) and Height of the first Tab Header
Dim X As Integer = TabControl1.GetTabRect(0).X
Dim Y As Integer = TabControl1.GetTabRect(0).Y
Dim Wid As Integer = 0
Dim Height As Integer = TabControl1.GetTabRect(0).Height
'Record the Width of all the Tab Headers
For Each tp As TabPage In TabControl1.TabPages
Wid += TabControl1.GetTabRect(TabControl1.TabPages.IndexOf(tp)).Width
Next
'Make both rectangles the same height (adding 2 will prevent a drawing issue where a line is drawn below the Tab Headers)
Rect1.Height = Height + 2
'Draw a rectangle for the area occupied by the TabHeaders
Rect2.X = X
Rect2.Y = Y
Rect2.Width = Wid
Rect2.Height = Height
'Add rectangle1 into a region
Dim reg As New Region(Rect1)
'Region.Xor cuts 1 rectangle out of another (in this case we are cuttting the rectangle occupied by the Tab Headers, out of the rectangle that
'is the same height as the tab headers and is the width of the TabControl). This will give us a region that surrounds the Tab Headers.
reg.Xor(Rect2)
'Now colour in the region using any colour you like
Dim brush As New SolidBrush(Color.FromArgb(0, 58, 140))
e.Graphics.FillRegion(brush, reg)
End Sub
Let me know if you have any probs with this as the VS2010 TabControl's leave this area transparent by default, so I can't test the code.
And moving onto the Flicker problem, add the following code to your project:
VB Code:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property 'CreateParams
The code overrides the forms window style. In this case it is telling the form to use the WS_CLIPCONTROLS constant (&H2000000); so now everytime the form redraws, it will not redraw the areas of the form occupied by child controls.
If for any reason you need to force a redraw on any of the controls on your form, you can do so by using:
Re: Tab pages backcolor & flicker
Quote:
Originally Posted by
jay20aiii
Hi,
This code is taken from an old project and should allow you to colour the area next to the TabHeaders:
(nb: Try the code in the Paint event. If you need to use the DrawItem Event you might need to set the TabControls DrawMode property to OwnerDrawFixed
If thats the case you will need to manually paint the TabHeaders and their text.)
VB Code:
'Colour in the area surrounding the Tab Headers (if you are using MultiLine Tabs, you will need to tweak this)
Private Sub TabControl1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles TabControl1.DrawItem
Dim Rect1 As Rectangle = TabControl1.Bounds 'Get the TabControl's rectangle
Dim Rect2 As New Rectangle
'Record the Left(X), Top(Y) and Height of the first Tab Header
Dim X As Integer = TabControl1.GetTabRect(0).X
Dim Y As Integer = TabControl1.GetTabRect(0).Y
Dim Wid As Integer = 0
Dim Height As Integer = TabControl1.GetTabRect(0).Height
'Record the Width of all the Tab Headers
For Each tp As TabPage In TabControl1.TabPages
Wid += TabControl1.GetTabRect(TabControl1.TabPages.IndexOf(tp)).Width
Next
'Make both rectangles the same height (adding 2 will prevent a drawing issue where a line is drawn below the Tab Headers)
Rect1.Height = Height + 2
'Draw a rectangle for the area occupied by the TabHeaders
Rect2.X = X
Rect2.Y = Y
Rect2.Width = Wid
Rect2.Height = Height
'Add rectangle1 into a region
Dim reg As New Region(Rect1)
'Region.Xor cuts 1 rectangle out of another (in this case we are cuttting the rectangle occupied by the Tab Headers, out of the rectangle that
'is the same height as the tab headers and is the width of the TabControl). This will give us a region that surrounds the Tab Headers.
reg.Xor(Rect2)
'Now colour in the region using any colour you like
Dim brush As New SolidBrush(Color.FromArgb(0, 58, 140))
e.Graphics.FillRegion(brush, reg)
End Sub
Let me know if you have any probs with this as the VS2010 TabControl's leave this area transparent by default, so I can't test the code.
And moving onto the Flicker problem, add the following code to your project:
VB Code:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property 'CreateParams
The code overrides the forms window style. In this case it is telling the form to use the WS_CLIPCONTROLS constant (&H2000000); so now everytime the form redraws, it will not redraw the areas of the form occupied by child controls.
If for any reason you need to force a redraw on any of the controls on your form, you can do so by using:
Thanks for your help buddy but the problems are still persisting.
- tab headers are coloured but the area next to them isn't. Actually I wanted the area next to tab headers to be colored and not the headers themself.
- the flicker problem is just like before.
- tab control does not have a paint event. I had to paste it in drawitem as the function said.
So we are still stuck there I guess.
Re: Tab pages backcolor & flicker
okies, you've pretty much got 3 choices with the TabPage Background.
1. Take a look at http://dotnetrix.co.uk/tabcontrol.htm. Specifically the OwnerDraw section. Lot's of work involved but it will get the result your looking for.
2. Create/download a Custom TabControl
3. Dock a Panel control onto the TabPage and use that for the background. See code below:
VB Code:
'CreateParams effect will work on the Panel.
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property 'CreateParams
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Panel1_Background()
End Sub
'Create Panel and set colour / properties
Private Panel1 As New Panel
Private Sub Panel1_Background()
Me.Controls.Add(Panel1)
Panel1.Dock = DockStyle.Fill
Panel1.Parent = TabControl1.TabPages(0)
Dim pBackground As New Bitmap(Panel1.Width, Panel1.Height)
Dim g As Graphics = Graphics.FromImage(pBackground)
Dim rect As New Rectangle(0, 0, pBackground.Width, pBackground.Height)
Dim b As New System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.FromArgb(0, 58, 140), Color.FromArgb(0, 215, 255), Drawing2D.LinearGradientMode.Vertical)
g.FillRectangle(b, rect)
g.Dispose()
Panel1.BackgroundImage = pBackground
Panel1.BackgroundImageLayout = ImageLayout.Stretch
End Sub
'Move panel onto next TabPage
Private Sub TabControl1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TabControl1.MouseDown
For i As Integer = 0 To TabControl1.TabCount - 1
If TabControl1.GetTabRect(i).Contains(e.Location) Then
Panel1.Parent = TabControl1.TabPages(i)
Exit For
End If
Next i
End Sub
I'll try and look at the code for colouring the TabHeaders area when I get chance.
Re: Tab pages backcolor & flicker
To get rid of the grey patch that you indicate in your picture try enabling visual styles.
Call this from your constructor
vb Code:
Application.EnableVisualStyles()
In order to paint the actual tabs you'll have to try what jay sugested.
Re: Tab pages backcolor & flicker
Thanks a lot Jay, I appreciate your help. :) The link you suggested should do the job.