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

时间:2011-04-06 15:50:33

标签: c# winforms

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

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

5 个答案:

答案 0 :(得分:3)

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

MSDN TabControl Appearance

答案 1 :(得分:2)

TabControl对自定义的支持很少。我用this custom tab control取得了很好的成功。如果你想像我一样改变外观,代码非常实用。

答案 2 :(得分:1)

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

  1. 在设计师或"手工"中,将Tab事件处理程序添加到TabPage:

    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);
    }
    

答案 3 :(得分:1)

首先,您需要从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_PAINT之前绘制其项目(标题标题)之前,因此我们的背景将被绘制在顶部,这使它们不可见。为了解决这个问题,我为EventHandler制作了DrawItem,其内容如下:

    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)。

答案 4 :(得分:0)

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