The situation is as follows, I have a custom TabControl that paints the TabHeaders itself so I can choose colors etc.
The problem occurs when I have more TabHeaders then the TabControl can fit and the arrows (spin control) appears. Whenever I then cycle all the way to the right (so there are no more headers to the right) the tabheader that was behind the arrows is still partially there.
Image to demonstrate:
What I know:
If I manually call .Invalidate() so it repaints the problem will go away, however I can't find an event that is triggered by the arrow keys (it does not have a scroll event).
Events that won't work:
- Click
- Layout
- Resize (don't even ask)
I had WndProc in mind (it has cases with get 'spin' which sounds like the spincontrol)
Custom tab control code:
class ColoredTabControl : TabControl
{
public Color ActiveTabColor
{
get
{
return _activeTabColor.Color;
}
set
{
_activeTabColor.Color = value;
this.Invalidate();
}
}
public Color DefaultTabColor
{
get
{
return _defaultTabColor.Color;
}
set
{
_defaultTabColor.Color = value;
this.Invalidate();
}
}
private SolidBrush _activeTabColor = new SolidBrush( Color.LightSteelBlue );
private SolidBrush _defaultTabColor = new SolidBrush( Color.LightGray );
private int _biggestTextHeight = 0;
private int _biggestTextWidth = 0;
public ColoredTabControl()
{
this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true );
}
protected override void OnPaint( PaintEventArgs e )
{
base.OnPaint( e );
var graphics = e.Graphics;
TabPage currentTab = this.SelectedTab;
if( TabPages.Count > 0 )
{
var biggestTextHeight = TabPages?.Cast<TabPage>()?.Max( r => TextRenderer.MeasureText( r.Text, r.Font ).Height );
var biggestTextWidth = TabPages?.Cast<TabPage>()?.Max( r => TextRenderer.MeasureText( r.Text, r.Font ).Width );
if( biggestTextHeight > _biggestTextHeight || biggestTextWidth > _biggestTextWidth )
{
_biggestTextWidth = ( int ) biggestTextWidth;
_biggestTextHeight = ( int ) biggestTextHeight;
this.ItemSize = new Size( _biggestTextWidth + 5, _biggestTextHeight + 10 );
}
}
for( int i = 0; i < TabPages.Count; i++ )
{
TabPage tabPage = TabPages[ i ];
Rectangle tabRectangle = GetTabRect( i );
SolidBrush brush = ( tabPage == currentTab ? _activeTabColor : _defaultTabColor );
graphics.FillRectangle( brush, tabRectangle );
TextRenderer.DrawText( graphics, tabPage.Text, tabPage.Font, tabRectangle, tabPage.ForeColor );
}
}
protected override void OnPaintBackground( PaintEventArgs e )
{
base.OnPaintBackground( e );
}
}
A bit of form code to repro the issue:
var tabControl = new ColoredTabControl() { Width = 340, Height = 300, Top = 100 };
tabControl.TabPages.Add( "text" );
tabControl.TabPages.Add( "another tab");
tabControl.TabPages.Add( "yet another" );
tabControl.TabPages.Add( "another one" );
tabControl.TabPages.Add( "another" );
tabControl.DefaultTabColor = Color.Red; //To see the issue clearly
Controls.Add( tabControl );
