如何在Winforms中更改选项卡控件的背景颜色?

有没有办法在winforms中更改选项卡控件的背景颜色,以便它周围没有白色边框?

我尝试了几种不同的方法,但它们都会导致显示相同的白色边框。

我只能想到将Appearance属性更改为Buttons

MSDN TabControl外观

TabControl对自定义的支持非常差。 我已经使用这个自定义选项卡控件取得了很好的成功。 如果你想像我一样改变外观,代码非常有用。

更简单(IMO):向TabPage添加一个绘制处理程序(不是顶级TabControl,而是其中的TabPage,然后以您想要的颜色绘制背景矩形)。

  1. 无论是在设计器中还是“手工”,都可以向TabPage添加一个Paint事件处理程序:

     Page1.Paint += tabpage_Paint; // custom paint event so we get the backcolor we want 
  2. 在paint方法中,将页面矩形绘制为您想要的颜色(在我的情况下,我希望它遵循标准的BackColor):

     // force the tab background to the current BackColor private void tabpage_Paint(object sender, PaintEventArgs e) { SolidBrush fillBrush = new SolidBrush(BackColor); e.Graphics.FillRectangle(fillBrush, e.ClipRectangle); } 

首先,您需要从TabControl创建一个派生类。 到目前为止一直很好,但现在它变脏了。

因为TabControl不会调用OnPaint ,所以我们会覆盖WndProc来处理WM_PAINT消息。 在那里,我们继续用我们喜欢的颜色绘制背景。

  protected override void WndProc(ref Message m) { base.WndProc(ref m); if(m.Msg == (int) WindowsMessages.Win32Messages.WM_PAINT) { using (Graphics g = this.CreateGraphics()) { //Double buffering stuff... BufferedGraphicsContext currentContext; BufferedGraphics myBuffer; currentContext = BufferedGraphicsManager.Current; myBuffer = currentContext.Allocate(g, this.ClientRectangle); Rectangle r = ClientRectangle; //Painting background if(Enabled) myBuffer.Graphics.FillRectangle(new SolidBrush(_backColor), r); else myBuffer.Graphics.FillRectangle(Brushes.LightGray, r); //Painting border r.Height = this.DisplayRectangle.Height +1; //Using display rectangle hight because it excludes the tab headers already rY = this.DisplayRectangle.Y - 1; //Same for Y coordinate r.Width -= 5; rX += 1; if(Enabled) myBuffer.Graphics.DrawRectangle(new Pen(Color.FromArgb(255, 133, 158, 191), 1), r); else myBuffer.Graphics.DrawRectangle(Pens.DarkGray, r); myBuffer.Render(); myBuffer.Dispose(); //Actual painting of items after Background was painted foreach (int index in ItemArgs.Keys) { CustomDrawItem(ItemArgs[index]); } } } } 

我正在进一步绘制这个方法,所以它看起来有点矫枉过正,但只是忽略了不必要的东西。 还要注意foreach循环。 我稍后会谈到这个。

问题是TabControl 其自己的WM_PAINT 之前绘制其项目(标题标题) 因此我们的背景将被绘制在顶部,这使它们不可见。 为了解决这个问题,我为DrawItem了一个EventHandler ,如下所示:

  private void DrawItemHandler(object sender, DrawItemEventArgs e) { //Save information about item in dictionary but dont do actual drawing if (!ItemArgs.ContainsKey(e.Index)) ItemArgs.Add(e.Index, e); else ItemArgs[e.Index] = e; } 

我将DrawItemEventArgs保存到字典中(在我的例子中称为“ItemArgs”),以便我以后可以访问它们。 这是几秒钟前的foreach发挥作用的地方。 它调用一个方法,我在绘制标题标题,它将我们之前保存的DrawItemEventArgs作为参数绘制为正确状态和位置的项目。

因此,简而言之,我们正在截取选项卡标题的绘图,以便在我们完成绘制背景之前将其延迟。

这个解决方案不是最优的,但是它可以工作,它是你唯一可以做的事情,可以更好地控制TabControl (lol),而无需从头开始绘制它。

将面板放在选项卡控件的顶部(不在其内部),并在属性中设置颜色。 根据需要调用Panelx.Hide()和Panelx.Show()。