繁体   English   中英

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

[英]How do I change background colour of tab control in Winforms?

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

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

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

首先,您需要从 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之前绘制其项目(选项卡标题),因此我们的背景将被绘制在顶部,这使得它们不可见。 为了解决这个问题,我为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),而无需从头开始绘制它。

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

MSDN TabControl 外观

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

  1. 在设计器中或“手动”中,将 Paint 事件处理程序添加到 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); }

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

不幸的是,在绘制控件时会处理背景颜色属性。 我的建议是做我所做的并创建一个用户控件来模仿标签控制器。

我使用菜单条作为选项卡,并将第二个用户控件停靠为父用户控件的填充。 在第二个用户控件中,我能够为所述选项卡添加我需要的任何内容。

更难的部分是您必须构建所有功能以使其用作选项卡控件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM