是否有办法在winforms中给选项卡的标签上色?

时间:2022-01-30 15:52:38

I am struggling to find way to color the tab headers of a tabpage in WinForms. There are solutions to color the current indexed tab using OnDrawItem event but can it be possible to color all the tabs with different colors at a time to make them intuitive for user for a certain behavior.

我正在努力寻找一种方法来在WinForms中为选项卡的页眉上色。有一些解决方案可以使用OnDrawItem事件给当前索引选项卡上色,但是否可以一次用不同的颜色给所有选项卡上色,以便用户对特定的行为感到直观。

Thanks in advance,

提前谢谢,

Rajeev Ranjan Lall

拉杰夫Ranjan拉尔

3 个解决方案

#1


25  

Yes, there is no need for any win32 code. You just need to set the tab controls DrawMode property to 'OwnerDrawFixed' and then handle the tab control's DrawItem event.

是的,不需要任何win32代码。您只需将选项卡控件DrawMode属性设置为“OwnerDrawFixed”,然后处理选项卡控件的DrawItem事件。

The following code shows how:

下面的代码展示了如何:

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    // This event is called once for each tab button in your tab control

    // First paint the background with a color based on the current tab

   // e.Index is the index of the tab in the TabPages collection.
    switch (e.Index )
    {
        case 0:
            e.Graphics.FillRectangle(new SolidBrush(Color.Red), e.Bounds);
            break;
        case 1:
            e.Graphics.FillRectangle(new SolidBrush(Color.Blue), e.Bounds);
            break;
        default:
            break;
    }

    // Then draw the current tab button text 
    Rectangle paddedBounds=e.Bounds;
    paddedBounds.Inflate(-2,-2);  
    e.Graphics.DrawString(tabControl1.TabPages[e.Index].Text, this.Font, SystemBrushes.HighlightText, paddedBounds);

}

Setting the DrawMode to 'OwnerDrawnFixed' means each tab button has to be the same size (ie Fixed).

将DrawMode设置为“OwnerDrawnFixed”意味着每个选项卡按钮必须是相同的大小(即固定)。

However if you want to change the size of all tab buttons, you can set the tab control's SizeMode property to 'Fixed' and then change the ItemSize property.

但是,如果您想要更改所有选项卡按钮的大小,可以将选项卡控件的SizeMode属性设置为“Fixed”,然后更改ItemSize属性。

#2


40  

An improved version of Ash's answer:

一个改进版的Ash的回答:

private void tabControl_DrawItem(object sender, DrawItemEventArgs e)
{
    TabPage page = tabControl.TabPages[e.Index];
    e.Graphics.FillRectangle(new SolidBrush(page.BackColor), e.Bounds);

    Rectangle paddedBounds = e.Bounds;
    int yOffset = (e.State == DrawItemState.Selected) ? -2 : 1;
    paddedBounds.Offset(1, yOffset);
    TextRenderer.DrawText(e.Graphics, page.Text, Font, paddedBounds, page.ForeColor);
}

This code uses the TextRenderer class to draw its text (as .NET does), fixes problems with font clipping/wrapping by not negatively inflating the bounds, and takes tab selection into account.

这个代码使用TextRenderer类来绘制它的文本(如。net所做的),通过不带负面影响的边界来修复字体剪切/包装的问题,并考虑到选项卡的选择。

Thanks to Ash for the original code.

感谢Ash提供的原始代码。

#3


1  

Using the current tab control, if it is possible you'd need to hook a lot of win-32 events (there may be a pre-wrapped implementation out there). Another alternative would be a 3rd-party tabbed control replacement; I'm sure plenty of vendors will sell you one.

使用当前选项卡控件,如果可能的话,您需要挂起许多win-32事件(可能有一个预先包装的实现)。另一种替代方案是由第三方提出的选项卡式控制替换方案;我肯定有很多商家会卖给你。

IMO, you might find it less pain to look at WPF; it is a big change, but has more control over things like this. You can host WPF inside winforms if needed (if you can't justify a full make-over, which is a pretty common reality).

在我看来,你可能会觉得看WPF不那么痛苦;这是一个巨大的变化,但对这类事情有更多的控制。如果需要的话,您可以在winforms中托管WPF(如果您不能证明完整的修改是合理的,这是一个非常常见的现实)。

#1


25  

Yes, there is no need for any win32 code. You just need to set the tab controls DrawMode property to 'OwnerDrawFixed' and then handle the tab control's DrawItem event.

是的,不需要任何win32代码。您只需将选项卡控件DrawMode属性设置为“OwnerDrawFixed”,然后处理选项卡控件的DrawItem事件。

The following code shows how:

下面的代码展示了如何:

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    // This event is called once for each tab button in your tab control

    // First paint the background with a color based on the current tab

   // e.Index is the index of the tab in the TabPages collection.
    switch (e.Index )
    {
        case 0:
            e.Graphics.FillRectangle(new SolidBrush(Color.Red), e.Bounds);
            break;
        case 1:
            e.Graphics.FillRectangle(new SolidBrush(Color.Blue), e.Bounds);
            break;
        default:
            break;
    }

    // Then draw the current tab button text 
    Rectangle paddedBounds=e.Bounds;
    paddedBounds.Inflate(-2,-2);  
    e.Graphics.DrawString(tabControl1.TabPages[e.Index].Text, this.Font, SystemBrushes.HighlightText, paddedBounds);

}

Setting the DrawMode to 'OwnerDrawnFixed' means each tab button has to be the same size (ie Fixed).

将DrawMode设置为“OwnerDrawnFixed”意味着每个选项卡按钮必须是相同的大小(即固定)。

However if you want to change the size of all tab buttons, you can set the tab control's SizeMode property to 'Fixed' and then change the ItemSize property.

但是,如果您想要更改所有选项卡按钮的大小,可以将选项卡控件的SizeMode属性设置为“Fixed”,然后更改ItemSize属性。

#2


40  

An improved version of Ash's answer:

一个改进版的Ash的回答:

private void tabControl_DrawItem(object sender, DrawItemEventArgs e)
{
    TabPage page = tabControl.TabPages[e.Index];
    e.Graphics.FillRectangle(new SolidBrush(page.BackColor), e.Bounds);

    Rectangle paddedBounds = e.Bounds;
    int yOffset = (e.State == DrawItemState.Selected) ? -2 : 1;
    paddedBounds.Offset(1, yOffset);
    TextRenderer.DrawText(e.Graphics, page.Text, Font, paddedBounds, page.ForeColor);
}

This code uses the TextRenderer class to draw its text (as .NET does), fixes problems with font clipping/wrapping by not negatively inflating the bounds, and takes tab selection into account.

这个代码使用TextRenderer类来绘制它的文本(如。net所做的),通过不带负面影响的边界来修复字体剪切/包装的问题,并考虑到选项卡的选择。

Thanks to Ash for the original code.

感谢Ash提供的原始代码。

#3


1  

Using the current tab control, if it is possible you'd need to hook a lot of win-32 events (there may be a pre-wrapped implementation out there). Another alternative would be a 3rd-party tabbed control replacement; I'm sure plenty of vendors will sell you one.

使用当前选项卡控件,如果可能的话,您需要挂起许多win-32事件(可能有一个预先包装的实现)。另一种替代方案是由第三方提出的选项卡式控制替换方案;我肯定有很多商家会卖给你。

IMO, you might find it less pain to look at WPF; it is a big change, but has more control over things like this. You can host WPF inside winforms if needed (if you can't justify a full make-over, which is a pretty common reality).

在我看来,你可能会觉得看WPF不那么痛苦;这是一个巨大的变化,但对这类事情有更多的控制。如果需要的话,您可以在winforms中托管WPF(如果您不能证明完整的修改是合理的,这是一个非常常见的现实)。