设置TabPage标签页的标题颜色

34

你好,

我有一个选项卡控件,想在事件触发时更改其中1个标签的文本颜色。我找到了如下两个回答:C# - TabPage Color eventC# Winform: How to set the Base Color of a TabControl (not the tabpage),但这些方法会更改所有标签页的颜色。

所以我想知道是否有一种以该特定标签为方法实现更改其颜色的方式?

类似于这样:

public void SetTabPageHeaderColor(TabPage page, Color color) 
{
    //Text Here
}
6个回答

47

如果你想要给选项卡添加颜色,可以尝试以下代码:

this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
this.tabControl1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.tabControl1_DrawItem);

private Dictionary<TabPage, Color> TabColors = new Dictionary<TabPage, Color>();
private void SetTabHeader(TabPage page, Color color)
{
    TabColors[page] = color;
    tabControl1.Invalidate();
}
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    //e.DrawBackground();
    using (Brush br = new SolidBrush (TabColors[tabControl1.TabPages[e.Index]]))
    {
        e.Graphics.FillRectangle(br, e.Bounds);
        SizeF sz = e.Graphics.MeasureString(tabControl1.TabPages[e.Index].Text, e.Font);
        e.Graphics.DrawString(tabControl1.TabPages[e.Index].Text, e.Font, Brushes.Black, e.Bounds.Left + (e.Bounds.Width - sz.Width) / 2, e.Bounds.Top + (e.Bounds.Height - sz.Height) / 2 + 1);

        Rectangle rect = e.Bounds;
        rect.Offset(0, 1);
        rect.Inflate(0, -1);
        e.Graphics.DrawRectangle(Pens.DarkGray, rect);
        e.DrawFocusRectangle();
    }
}

基于事件,我想要一个类似于“SetTabHeader(TabPage page, Color color)”的方法。 - Theun Arbeider
@Levisaxos,我已经添加了你需要的方法。但是你仍然需要事件。 - Fun Mun Pieng
2
很好的答案,但在Windows 8上效果不太好。将绘图模式设置为OwnerDrawFixed并添加绘图事件会使选项卡顶部以与通常不同的方式绘制。 - Björn Lindqvist
1
对于不在TabColors中的选项卡页面,我们如何使用默认的DrawItem? - Jimmy
请问是否有可能将选项卡标题底部的白色边框/区域也进行覆盖/着色?请在这里查看图片ibb.co/n1F1p57,非选定的选项卡标题上的白色底部边框看起来很奇怪。提前感谢! - SalmaBegum

22

对于阅读此内容的 WinForms 用户 - 只有在将选项卡控件的 DrawMode 设置为 OwnerDrawFixed 时,此代码才有效 - 如果设置为 Normal,则永远不会触发 DrawItem 事件。


9

补充Fun Mun Pieng的答案,该答案适用于水平选项卡,如果您要使用垂直选项卡(就像我一样),则需要类似于以下内容:

    private void tabControl2_DrawItem(object sender, DrawItemEventArgs e)
    {
        using (Brush br = new SolidBrush(tabColorDictionary[tabControl2.TabPages[e.Index]]))
        {
            // Color the Tab Header
            e.Graphics.FillRectangle(br, e.Bounds);
            // swap our height and width dimensions
            var rotatedRectangle = new Rectangle(0, 0, e.Bounds.Height, e.Bounds.Width);

            // Rotate
            e.Graphics.ResetTransform();
            e.Graphics.RotateTransform(-90);

            // Translate to move the rectangle to the correct position.
            e.Graphics.TranslateTransform(e.Bounds.Left, e.Bounds.Bottom, System.Drawing.Drawing2D.MatrixOrder.Append);

            // Format String
            var drawFormat = new System.Drawing.StringFormat();
            drawFormat.Alignment = StringAlignment.Center;
            drawFormat.LineAlignment = StringAlignment.Center;

            // Draw Header Text
            e.Graphics.DrawString(tabControl2.TabPages[e.Index].Text, e.Font, Brushes.Black, rotatedRectangle, drawFormat);
        }
    }

我会 echo ROJO1969 所说的观点,如果这是在 WinForms 中 - 那么你必须将 DrawMode 设置为 OwnerDrawFixed。
特别感谢这篇精彩的 博客文章,它描述了如何在表单上旋转文本。

2
private void MainForm_Load(object sender, EventArgs e)
{
       ...    
                
       this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
       this.tabControl1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.tabControl1_DrawItem);
       ...
}


private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
     try
     {   
          // Draw the background of the control for each item.
          //e.DrawBackground();
            
          if (e.Index == this.tabControl1.SelectedIndex)
          {
              Brush _BackBrush = new SolidBrush(tabControl1.TabPages[e.Index].BackColor);
                   

              Rectangle rect = e.Bounds;
              e.Graphics.FillRectangle(_BackBrush, (rect.X) + 4, rect.Y, (rect.Width) - 4, rect.Height);
                    
              SizeF sz = e.Graphics.MeasureString(tabControl1.TabPages[e.Index].Text, e.Font);
              e.Graphics.DrawString(tabControl1.TabPages[e.Index].Text, e.Font, Brushes.Black,
                         e.Bounds.Left + (e.Bounds.Width - sz.Width) / 2,
                         e.Bounds.Top + (e.Bounds.Height - sz.Height) / 2 + 1);

         }
         else
         {   
              // 파스톤계 배경색 없앨려면 FromArgb 를 없애면 된다.
              Brush _BackBrush = new SolidBrush(Color.FromArgb(50, tabControl1.TabPages[e.Index].BackColor));

              Rectangle rect = e.Bounds;
              e.Graphics.FillRectangle(_BackBrush, rect.X, (rect.Y)-0, rect.Width, (rect.Height)+6);

              SizeF sz = e.Graphics.MeasureString(tabControl1.TabPages[e.Index].Text, e.Font);
              e.Graphics.DrawString(tabControl1.TabPages[e.Index].Text, e.Font, Brushes.Black, 
              e.Bounds.Left + (e.Bounds.Width - sz.Width) / 2,
                        e.Bounds.Top + 5);
                    
         }
            
     }
     catch (Exception Ex)
     {
          MessageBox.Show(Ex.Message, "Error Occured", MessageBoxButtons.OK, MessageBoxIcon.Information);

     }
}

2
如果有人需要为选项卡标题添加颜色,请尝试以下方法。我的选项卡名称是tabControl。
tabControl.DrawMode = TabDrawMode.OwnerDrawFixed;
tabControl.DrawItem += tabControl1_DrawItem;

在主类下声明此内容,然后:
 private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
            {
                e.DrawBackground();
                Color tabTextColor = Color.FromArgb(0x000001);
                var color = Color.FromArgb(tabTextColor.R, tabTextColor.G, tabTextColor.B); 
                TextRenderer.DrawText(e.Graphics, tabControl.TabPages[e.Index].Text, e.Font, e.Bounds, color);
            }

声明这个函数将生成输出。 最终输出

这段代码的蓝色背景是从哪里来的? - MX313
1
蓝色将出现在焦点选项卡的背景中。这是TextRenderer.DrawText的预定义行为。 - samy nathan
但是为什么你要从这里复制粘贴我的答案呢?好吧,最后你替换了颜色部分,将几乎透明的颜色变成了几乎黑色... - György Kőszeg
@MX313:它来自于 e.DrawBackground,它尊重要绘制项的 State。@SamyNathan 表示它来自于 TextRenderer.DrawText,但它不会绘制任何背景。顺便说一下,如果启用了视觉样式,当未设置 OwnerDrawFixed 时,背景将以不同方式绘制,但您可以根据其他答案的建议省略 e.DrawBackground(),并自己绘制背景进行自定义。 - György Kőszeg

0
一个对samy答案的详细说明...如果你需要一个单独的选项卡以不同的颜色突出显示,比如粉色作为警报选项卡,那么其他选项卡仍然可以正常工作但仍然突出显示焦点,我添加了以下内容:
private void tabControlMain_DrawItem(object sender, DrawItemEventArgs e)
        {

            if (e.Index == iTabIndexDiffColor)
            {
                Color cColor =  Color.LightPink;
                using (Brush br = new SolidBrush(cColor))
                {
                    e.Graphics.FillRectangle(br, e.Bounds);
                    SizeF sz = e.Graphics.MeasureString(tabControlMain.TabPages[e.Index].Text, e.Font);
                    e.Graphics.DrawString(tabControlMain.TabPages[e.Index].Text, e.Font, Brushes.Black, e.Bounds.Left + (e.Bounds.Width - sz.Width) / 2, e.Bounds.Top + (e.Bounds.Height - sz.Height) / 2 + 1);

                    Rectangle rect = e.Bounds;
                    rect.Offset(0, 1);
                    rect.Inflate(0, -1);
                    e.Graphics.DrawRectangle(Pens.DarkGray, rect);
                    e.DrawFocusRectangle();
                }
            }
            else
            {
                e.DrawBackground();
                Color color; Color tabTextColor;
                if (e.Index == tabControlMain.SelectedIndex)
                    color = Color.White;
                else
                {
                    tabTextColor = Color.FromArgb(0x000001);
                    color = Color.FromArgb(tabTextColor.R, tabTextColor.G, tabTextColor.B);
                }
                TextRenderer.DrawText(e.Graphics, tabControlMain.TabPages[e.Index].Text, e.Font, e.Bounds, color);
            }
        }`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接