我遇到了类似的问题,尽管是在一个自绘的列表框上。我的解决方案是使用BufferedGraphics对象。如果你的列表框不是自绘的,你的情况可能会有所不同,但也许这个解决方案会给你一些启示。
我发现,如果我没有提供TextFormatFlags.PreserveGraphicsTranslateTransform参数,TextRenderer很难渲染到正确的位置。另一种方法是使用P/Invoke调用BitBlt来直接在图形上下文之间复制像素。我选择了这种方式,因为这是两种恶中较轻的一种。
public sealed class DoubleBufferedListBox : ListBox
{
#region Method Overrides
protected override void OnDrawItem(DrawItemEventArgs e)
{
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
Rectangle newBounds = new Rectangle(0, 0, e.Bounds.Width, e.Bounds.Height);
using (BufferedGraphics bufferedGraphics = currentContext.Allocate(e.Graphics, newBounds))
{
DrawItemEventArgs newArgs = new DrawItemEventArgs(
bufferedGraphics.Graphics, e.Font, newBounds, e.Index, e.State, e.ForeColor, e.BackColor);
base.OnDrawItem(newArgs);
GDI.CopyGraphics(e.Graphics, e.Bounds, bufferedGraphics.Graphics, new Point(0, 0));
}
}
#endregion
}
由frenchtoast建议的GDI
类。
public static class GDI
{
private const UInt32 SRCCOPY = 0x00CC0020;
[DllImport("gdi32.dll", CallingConvention = CallingConvention.StdCall)]
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, UInt32 dwRop);
public static void CopyGraphics(Graphics g, Rectangle bounds, Graphics bufferedGraphics, Point p)
{
IntPtr hdc1 = g.GetHdc();
IntPtr hdc2 = bufferedGraphics.GetHdc();
BitBlt(hdc1, bounds.X, bounds.Y,
bounds.Width, bounds.Height, hdc2, p.X, p.Y, SRCCOPY);
g.ReleaseHdc(hdc1);
bufferedGraphics.ReleaseHdc(hdc2);
}
}
Graphics GDI = this.CreateGraphics();
但它没有CopyGraphics方法。或者你之前导入了Gdi32.dll吗? - MattOnDrawItem
是在我改变了DrawMode
之后被调用的。现在我可以看到我在 BitBlt 方面有一些问题,因为 ListBox 窗口完全是空的 - 我必须解决这个问题。 - MattGDI.CopyGraphics
зҡ„еҢ…иЈ…ж–№жі•пјҹ - Jeremy Thompson