C# 在listview上绘制将禁用对listview项的重画

C# 在listview上绘制将禁用对listview项的重画,c#,.net,winforms,listview,gdi+,C#,.net,Winforms,Listview,Gdi+,这是什么原因 我覆盖了PaintBackground并绘制了一个字符串。直到我在构造函数中调用它,它才会显示: this.SetStyle ( ControlStyles.UserPaint, true ); 但是我在listview中看不到这些项目 为什么以及如何解决这个问题 编辑:代码 protected override void OnPaintBackground ( PaintEventArgs pevent ) { base.OnPaintBackg

这是什么原因

我覆盖了PaintBackground并绘制了一个字符串。直到我在构造函数中调用它,它才会显示:

this.SetStyle ( ControlStyles.UserPaint, true );
但是我在listview中看不到这些项目

为什么以及如何解决这个问题

编辑:代码

    protected override void OnPaintBackground ( PaintEventArgs pevent )
    {
        base.OnPaintBackground ( pevent );

        // Create string to draw.
        String drawString = "76";

        // Create font and brush.
        Font drawFont = new Font ( "Arial", 36 );
        SolidBrush drawBrush = new SolidBrush ( Color.Blue );

        // Create point for upper-left corner of drawing.
        PointF drawPoint = new PointF ( 150.0F, 150.0F );

        // Draw string to screen.
        pevent.Graphics.DrawString ( drawString, drawFont, drawBrush, drawPoint );

        //pevent.Graphics.FillRectangle ( drawBrush, this.ClientRectangle );
    }`enter code here`

正如我在关于这个主题的最后一个线程中所说,
OnPaint()
UserPaint
不适用于ListView。绘画由底层控件处理,不能以这种方式截取。这与其他控件不同

因此,当
ControlStyles.UserPaint
true
时,底层控件不会被告知重新绘制自身。相反,所有图形都被路由到
OnPaintBackground()
OnPaint()
方法,正如您所发现的,这些方法什么也不做

有两种方法可以满足您的要求(第二种方法优于第一种方法):

第一种方法:截取
WM_PAINT
,进行基本处理,然后绘制到列表视图上。大概是这样的:

public class MyListView : ListView
{
    protected override void WndProc(ref Message m) {
        switch (m.Msg) {
            case 0x0F: // WM_PAINT
                this.HandlePaint(ref m);
                break;
            default:
                base.WndProc(ref m);
                break;
        }
    }

    protected virtual void HandlePaint(ref Message m) {
        base.WndProc(ref m);

        using (Graphics g = this.CreateGraphics()) {
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            sf.Trimming = StringTrimming.EllipsisCharacter;
            g.DrawString("Some text", new Font("Tahoma", 13),
                SystemBrushes.ControlDark, this.ClientRectangle, sf);
        }
    }
}
但是,当您绘制的内容超出listview认为保存控件内容的区域时,这会导致重新绘制问题——它不会触发绘制事件

第二种方式:截取CustomDraw通知(这与OwnerDraw不同),并监听
CDDS\u POSTPAINT
阶段。在此阶段,您可以安全地在列表视图上绘制。您可以查看的代码来了解它是如何完成的


您也可以省去很多麻烦,直接使用ObjectListView:)

正如我在关于这个主题的最后一个线程中所说,
OnPaint()
UserPaint
不使用ListView。绘画由底层控件处理,不能以这种方式截取。这与其他控件不同

因此,当
ControlStyles.UserPaint
true
时,底层控件不会被告知重新绘制自身。相反,所有图形都被路由到
OnPaintBackground()
OnPaint()
方法,正如您所发现的,这些方法什么也不做

有两种方法可以满足您的要求(第二种方法优于第一种方法):

第一种方法:截取
WM_PAINT
,进行基本处理,然后绘制到列表视图上。大概是这样的:

public class MyListView : ListView
{
    protected override void WndProc(ref Message m) {
        switch (m.Msg) {
            case 0x0F: // WM_PAINT
                this.HandlePaint(ref m);
                break;
            default:
                base.WndProc(ref m);
                break;
        }
    }

    protected virtual void HandlePaint(ref Message m) {
        base.WndProc(ref m);

        using (Graphics g = this.CreateGraphics()) {
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            sf.Trimming = StringTrimming.EllipsisCharacter;
            g.DrawString("Some text", new Font("Tahoma", 13),
                SystemBrushes.ControlDark, this.ClientRectangle, sf);
        }
    }
}
但是,当您绘制的内容超出listview认为保存控件内容的区域时,这会导致重新绘制问题——它不会触发绘制事件

第二种方式:截取CustomDraw通知(这与OwnerDraw不同),并监听
CDDS\u POSTPAINT
阶段。在此阶段,您可以安全地在列表视图上绘制。您可以查看的代码来了解它是如何完成的


您也可以省去很多麻烦,直接使用ObjectListView:)

您正在调用base.OnPaintBackground()吗?您可以发布覆盖中的代码吗?以下属性和样式的值是什么ControlStyles.DoubleBuffer-ControlStyles.AllPaintingInWmPaint-ListView。OwnerDraw@Sheng,没有别的了。我刚刚添加了UserPaint,仅此而已。您正在调用base.OnPaintBackground()?您可以发布覆盖中的代码吗?以下属性和样式的值是什么ControlStyles.DoubleBuffer-ControlStyles.AllPaintingInWmPaint-ListView。OwnerDraw@Sheng,没有别的了。我刚刚添加了UserPaint,仅此而已。谢谢语法学家,我将切换到您的列表视图。顺便说一句,我刚刚切换到您的列表视图,这很好。但是遇到了鼠标点击测试的强制转换异常,尽管我在代码中没有使用这些事件。感谢语法学家,我将切换到您的列表视图。顺便说一句,我刚刚切换到您的列表视图,这很好。但在鼠标点击测试中遇到了强制转换异常,尽管我在代码中没有使用这些事件。