TabControl and borders visual glitch
I have these visual glitches on every tabControls
when I am changing its tabPages
BackColor
and the BackColor
of the form, as illustrated on the following images:
- At the top of the
tabPage
, there is an interior one-pixel white border. - At the left of the
tabPage
, there is an interior three-pixels white border. - At the bottom of the
tabPage
, there is an interior one-pixel white border and an exterior two-pixels white开发者_JAVA技巧 border. - At the right of the
tabPage
, there is an interior one-pixel white border and an exterior two-pixels white border.
Is there a way I can get rid of those white borders?
Here's my attempted hack. I used a NativeWindow
to draw over the TabControl
to fill in those "white" spaces. I won't claim it's perfect:
public class TabPadding : NativeWindow {
private const int WM_PAINT = 0xF;
private TabControl tabControl;
public TabPadding(TabControl tc) {
tabControl = tc;
tabControl.Selected += new TabControlEventHandler(tabControl_Selected);
AssignHandle(tc.Handle);
}
void tabControl_Selected(object sender, TabControlEventArgs e) {
tabControl.Invalidate();
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_PAINT) {
using (Graphics g = Graphics.FromHwnd(m.HWnd)) {
//Replace the outside white borders:
if (tabControl.Parent != null) {
g.SetClip(new Rectangle(0, 0, tabControl.Width - 2, tabControl.Height - 1), CombineMode.Exclude);
using (SolidBrush sb = new SolidBrush(tabControl.Parent.BackColor))
g.FillRectangle(sb, new Rectangle(0,
tabControl.ItemSize.Height + 2,
tabControl.Width,
tabControl.Height - (tabControl.ItemSize.Height + 2)));
}
//Replace the inside white borders:
if (tabControl.SelectedTab != null) {
g.ResetClip();
Rectangle r = tabControl.SelectedTab.Bounds;
g.SetClip(r, CombineMode.Exclude);
using (SolidBrush sb = new SolidBrush(tabControl.SelectedTab.BackColor))
g.FillRectangle(sb, new Rectangle(r.Left - 3,
r.Top - 1,
r.Width + 4,
r.Height + 3));
}
}
}
}
}
And to hook it up:
public Form1() {
InitializeComponent();
var tab = new TabPadding(tabControl1);
}
My end result:
you can inherit from control
public class TabControlEx : TabControl
{
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x1300 + 40)
{
RECT rc = (RECT)m.GetLParam(typeof(RECT));
rc.Left -= 0;
rc.Right += 3;
rc.Top -= 0;
rc.Bottom += 3;
Marshal.StructureToPtr(rc, m.LParam, true);
}
base.WndProc(ref m);
}
}
internal struct RECT { public int Left, Top, Right, Bottom; }
I recently ran into this problem and never found a good simple solution. That's when I thought about simply adjusting the control's clipping region. This seemed to work just fine with no noticeable side-effects. The 2 extra white pixels on the right side and the one extra white pixel at the bottom are no longer visible.
class TabControlEx : TabControl
{
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0005) // WM_SIZE
{
int Width = unchecked((short)m.LParam);
int Height = unchecked((short)((uint)m.LParam >> 16));
// Remove the annoying white pixels on the outside of the tab control
// by adjusting the control's clipping region to exclude the 2 pixels
// on the right and one pixel on the bottom.
Region = new Region(new Rectangle(0, 0, Width - 2, Height - 1));
}
base.WndProc(ref m);
}
}
精彩评论