C# 在listview上绘制将禁用对listview项的重画
这是什么原因 我覆盖了PaintBackground并绘制了一个字符串。直到我在构造函数中调用它,它才会显示: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
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,仅此而已。谢谢语法学家,我将切换到您的列表视图。顺便说一句,我刚刚切换到您的列表视图,这很好。但是遇到了鼠标点击测试的强制转换异常,尽管我在代码中没有使用这些事件。感谢语法学家,我将切换到您的列表视图。顺便说一句,我刚刚切换到您的列表视图,这很好。但在鼠标点击测试中遇到了强制转换异常,尽管我在代码中没有使用这些事件。