C# 如何在Winforms中更改选项卡控件的背景颜色?
有没有办法在winforms中更改选项卡控件的背景颜色,使其周围没有白色边框C# 如何在Winforms中更改选项卡控件的背景颜色?,c#,winforms,C#,Winforms,有没有办法在winforms中更改选项卡控件的背景颜色,使其周围没有白色边框 我尝试了几种不同的方法,但它们都会显示相同的白色边框。我只能考虑将外观属性更改为按钮 TabControl对定制的支持非常差。我成功地使用了它。如果您想像我一样更改外观,那么代码非常有用。更简单(IMO):向TabPage(不是顶级TabControl,而是其中的TabPage)添加绘制处理程序,然后以您想要的颜色绘制背景矩形 在设计器或“手动”中,向选项卡页添加绘制事件处理程序: Page1.Paint += tab
我尝试了几种不同的方法,但它们都会显示相同的白色边框。我只能考虑将外观属性更改为按钮
TabControl
对定制的支持非常差。我成功地使用了它。如果您想像我一样更改外观,那么代码非常有用。更简单(IMO):向TabPage(不是顶级TabControl,而是其中的TabPage)添加绘制处理程序,然后以您想要的颜色绘制背景矩形
Page1.Paint += tabpage_Paint; // custom paint event so we get the backcolor we want
首先,您需要从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
r.Y = this.DisplayRectangle.Y - 1; //Same for Y coordinate
r.Width -= 5;
r.X += 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_绘制之前绘制它的项目(选项卡标题),因此我们的背景将绘制在顶部,从而使它们不可见。为了解决这个问题,我为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
作为参数保存,以在正确的状态和位置绘制项目
因此,简而言之,我们正在拦截选项卡标题的绘制,以将其延迟到完成背景绘制为止
此解决方案不是最佳解决方案,但它可以工作,而且这是您唯一可以做的事情,您可以在不从头开始绘制的情况下对选项卡控件进行更多控制。在选项卡控件顶部(而不是内部)放置一个面板,并在属性中设置颜色。
根据需要调用Panelx.Hide()和Panelx.Show()。我认为这并不能解决Tom需要更改边缘和顶部选项卡本身(即标题)颜色的问题TabPress自身的客户端区域如您所描述的那样改变,也可以通过设计器中的TabPab.BuffCuy来完成。使用RHAPSODY的CODEPROTER链接,也可以检查LauraM对其局限性的回答:最后,也考虑这个线程:这只会改变标签项的背景而不是头的背景!没有CRE的好解决方案!创建一个新控件并使用BufferedGraphic我注意到在使用此控件时出现了一个问题。当选项卡比选项卡控件宽,因此这两个箭头出现时,所有内容都会分离。我建议避免这种情况。实现这一点的唯一方法是绘制选项卡控件本身。在CodeProject.com上,您可以获得主题颜色。您可以关闭控件的视觉样式,但这会使其返回到战舰灰色,仍然无法更改。
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;
}