如何在Winforms中更改选项卡控件的背景颜色?
有没有办法在winforms中更改选项卡控件的背景颜色,以便它周围没有白色边框?
我尝试了几种不同的方法,但它们都会导致显示相同的白色边框。
我只能想到将Appearance属性更改为Buttons
MSDN TabControl外观
TabControl
对自定义的支持非常差。 我已经使用这个自定义选项卡控件取得了很好的成功。 如果你想像我一样改变外观,代码非常有用。
更简单(IMO):向TabPage添加一个绘制处理程序(不是顶级TabControl,而是其中的TabPage,然后以您想要的颜色绘制背景矩形)。
-
无论是在设计器中还是“手工”,都可以向TabPage添加一个Paint事件处理程序:
Page1.Paint += tabpage_Paint; // custom paint event so we get the backcolor we want
-
在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()。