更改Winform ListView标题的背景颜色

18

如何更改ListView标题的背景颜色?


1
你需要通过覆盖Paint事件来实现自定义绘图。 - Mitch Wheat
重写Paint方法对ListView没有任何作用。您需要使用@David建议的OwnerDraw机制。只需记住,这样做会从标题控件中删除所有样式--没有热项,没有排序指示器,没有渐变背景。 - Grammarian
4个回答

23
你可以通过将列表视图的OwnerDraw属性设置为true来实现此操作。
然后,您可以为列表视图的绘制事件提供事件处理程序。 MSDN上有一个详细的示例。
以下是将标题颜色设置为红色的示例代码:
    private void listView1_DrawColumnHeader(object sender,
                                            DrawListViewColumnHeaderEventArgs e)
    {
        e.Graphics.FillRectangle(Brushes.Red, e.Bounds);
        e.DrawText();
    }

我认为(但很乐意被证明是错误的),如果将OwnerDraw设置为true,则还需要提供其他绘制事件的处理程序,这些事件具有如下所示的默认实现:

    private void listView1_DrawItem(object sender,
                                    DrawListViewItemEventArgs e)
    {
        e.DrawDefault = true;
    }

我确实无法使列表视图在没有此操作的情况下绘制项目。


2
作为警告,因为我花了一个多小时才弄明白,不要在drawcolumnheader内部放置MSGBOX命令!这会卡住vb.net - 否则工作正常。 - cardmagik

21

我知道我来晚了,但我还是看到了这篇帖子,它对我很有帮助。这里是一个简单的代码示例,基于David提供的代码。

using System.Windows.Forms;
using System.Drawing;

//List view header formatters
public static void colorListViewHeader(ref ListView list, Color backColor, Color foreColor)
{
    list.OwnerDraw = true;
    list.DrawColumnHeader += 
        new DrawListViewColumnHeaderEventHandler
        (
            (sender, e) => headerDraw(sender, e, backColor, foreColor)
        );
    list.DrawItem += new DrawListViewItemEventHandler(bodyDraw);
}

private static void headerDraw(object sender, DrawListViewColumnHeaderEventArgs e, Color backColor, Color foreColor)
{
    using (SolidBrush backBrush = new SolidBrush(backColor))
    {
        e.Graphics.FillRectangle(backBrush, e.Bounds);
    }

    using (SolidBrush foreBrush = new SolidBrush(foreColor))
    {
        e.Graphics.DrawString(e.Header.Text, e.Font, foreBrush, e.Bounds);
    }
}

private static void bodyDraw(object sender, DrawListViewItemEventArgs e)
{
    e.DrawDefault = true;
}

然后在您的表单构造函数中调用此函数。

public Form()
{
    InitializeComponent();
    *CLASS NAME*.colorListViewHeader(ref myListView, *SOME COLOR*, *SOME COLOR*);
}

只需将*CLASS NAME*替换为您放置第一段代码的类名,将*SOME COLOR*替换为某种颜色即可。

//Some examples:
Color.white
SystemColors.ActiveCaption
Color.FromArgb(0, 102, 255, 102);

谢谢,这很好。然而,这还不是全部。我还没有解决以下问题,但我注意到的是:水平对齐属性未评估垂直对齐未设置(默认居中?)缺少鼠标悬停效果字体呈现非常块状(e.Graphics.TextRenderingHintClearTypeGridFit没有帮助)。尽管这应该很简单,但手动完成的工作实在令人失望。 - Ralf

3

现在已经是2023年了,我不知道David的答案在2009年是否有效,但今天在屏幕上看起来真的很丑陋。它没有绘制所有的文本,可能只有第一个字母。

Nick Pray提供了更好的解决方案,可以在今天使用,但需要考虑一些事情。首先,文本显示在右上角,因此您需要将其格式化为绘图的一部分。此外,每个列之间没有线条显示,因此也需要进行设置。

基于Nick的示例,我进行了一些修改,希望这能帮到您。

    private void ListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
    {
        //Fills one solid background for each cell.
        using (SolidBrush backBrush = new SolidBrush(Color.FromArgb(6, 128, 128)))
        {
            e.Graphics.FillRectangle(backBrush, e.Bounds);
        }
        //Draw the borders for the header around each cell.
        using (Pen backBrush = new Pen(Color.Wheat))
        {
            e.Graphics.DrawRectangle(backBrush, e.Bounds);
        }
        using (SolidBrush foreBrush = new SolidBrush(Color.White))
        {
            //Since e.Header.TextAlign returns 'HorizontalAlignment' with values of (Right, Center, Left).  
            //DrawString uses 'StringAlignment' with values of (Near, Center, Far). 
            //We must translate these and setup a vertical alignment that doesn't exist in DrawListViewColumnHeaderEventArgs.
            StringFormat stringFormat = GetStringFormat(e.Header.TextAlign);

            //Do some padding, since these draws right up next to the border for Left/Near.  Will need to change this if you use Right/Far
            Rectangle rect = e.Bounds; rect.X += 2;
            e.Graphics.DrawString(e.Header.Text, e.Font, foreBrush, rect, stringFormat);
        }
    }

    private StringFormat GetStringFormat(HorizontalAlignment ha)
    {
        StringAlignment align;

        switch (ha)
        {
            case HorizontalAlignment.Right:
                align = StringAlignment.Far;
                break;
            case HorizontalAlignment.Center:
                align = StringAlignment.Center;
                break;
            default:
                align = StringAlignment.Near;
                break;
        }

        return new StringFormat()
        {
            Alignment = align,
            LineAlignment = StringAlignment.Center
        };
    }

0

要改变标题的颜色并保持文本垂直居中,可以这样做:

您可以像这样挂钩listView的DrawColumnHeader:

listView1.DrawColumnHeader += new DrawListViewColumnHeaderEventHandler(listView1_DrawColumnHeader);

那么事件将会是这样的:

    private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
    {
        e.Graphics.FillRectangle(Brushes.LightBlue, e.Bounds); //Fill header with color

        //Adjust the position of the text to be vertically centered
        int yOffset = (e.Bounds.Height - e.Graphics.MeasureString(e.Header.Text, e.Font).ToSize().Height) / 2;
        Rectangle newBounds = new Rectangle(e.Bounds.X, e.Bounds.Y + yOffset, e.Bounds.Width, e.Bounds.Height - yOffset);

        e.Graphics.DrawString(e.Header.Text, e.Font, Brushes.Black, newBounds);
    }

如果这对您有帮助,请告诉我!


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