SLa*_*aks 8 .net c# listbox doublebuffered winforms
我有一个CheckedListBox(WinForms)控件(它继承自ListBox; googling显示问题在于ListBox),它固定在其表单的所有四个边上.调整窗体大小时,ListBox有一个丑陋的闪烁.我想继承CheckedListBox和设置DoubleBuffered,以true在构造函数(此技术也适用于其他控件,包括ListView和DataGridView中),但它没有任何效果.
我尝试添加WS_EX_COMPOSITED样式CreateParams,这有帮助,但使表单调整大小更慢.
有没有其他方法可以防止这种闪烁?
Eri*_*ric 12
我有类似的问题,虽然有一个所有者绘制的列表框.我的解决方案是使用BufferedGraphics对象.如果您的清单不是所有者绘制的,那么您的里程可能因此解决方案而异,但也许它会给您一些灵感.
我发现TextRenderer很难渲染到正确的位置,除非我提供了TextFormatFlags.PreserveGraphicsTranslateTransform.替代方法是使用P/Invoke调用BitBlt直接在图形上下文之间复制像素.我选择这个作为两个邪恶的较小者.
/// <summary>
/// This class is a double-buffered ListBox for owner drawing.
/// The double-buffering is accomplished by creating a custom,
/// off-screen buffer during painting.
/// </summary>
public sealed class DoubleBufferedListBox : ListBox
{
#region Method Overrides
/// <summary>
/// Override OnTemplateListDrawItem to supply an off-screen buffer to event
/// handlers.
/// </summary>
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);
// Supply the real OnTemplateListDrawItem with the off-screen graphics context
base.OnDrawItem(newArgs);
// Wrapper around BitBlt
GDI.CopyGraphics(e.Graphics, e.Bounds, bufferedGraphics.Graphics, new Point(0, 0));
}
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
该GDI课程(由frenchtoast建议).
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6612 次 |
| 最近记录: |