双缓冲不适用于组合框。 还有其他方法可以避免 Windows 窗体中的闪烁吗?
我有一个窗口窗体,其中有许多面板。根据我的菜单选择,我一次仅显示一个面板。
我有一个图标面板、一个标题面板和组合框。根据该组合框的选定项目,gridview1 和 2 正在填充。当我使用键盘向下箭头快速选择组合框项目时,图标面板和标题面板总是重新绘制。我需要保留两者而不做任何改变。当我更改组合框选定的索引时,这两个面板会产生一些闪烁效果(即它们正在闪烁或闪烁)。有什么办法可以避免这种闪烁吗?我尝试在表单构造函数和表单加载事件中启用双缓冲。
请帮忙。
InitializeComponent();
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, false);
this.SetStyle(ControlStyles.Opaque, false);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
我已经在表单构造函数和表单加载事件中尝试过此代码。
另一个解决方案:
//TODO: Don't forget to include using System.Runtime.InteropServices.
internal static class NativeWinAPI
{
internal static readonly int GWL_EXSTYLE = -20;
internal static readonly int WS_EX_COMPOSITED = 0x02000000;
[DllImport("user32")]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32")]
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
}
您的表单构造函数应如下所示:
public MyForm()
{
InitializeComponent();
int style = NativeWinAPI.GetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE);
style |= NativeWinAPI.WS_EX_COMPOSITED;
NativeWinAPI.SetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE, style);
}
在上面的代码中,您可以将
this.Handle
更改为 MyFlickeringPanel.Handle
您可以在这里阅读更多相关信息:扩展窗口样式和这里:CreateWindowEx。
设置 WS_EX_COMPOSITED 后,窗口的所有后代都会获得 使用双缓冲从下到上的绘制顺序。从下到上 绘画顺序允许后代窗口具有半透明度(alpha) 和透明度(颜色键)效果,但前提是后代 窗口还设置了 WS_EX_TRANSPARENT 位。双缓冲允许 窗口及其后代的绘制不会闪烁。
protected override CreateParams CreateParams
{
get
{
CreateParams handleParam = base.CreateParams;
handleParam.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
return handleParam;
}
}
解决方案#1:
添加项目之前使用
ComboxBox.BeginUpdate()
。这将防止每次将项目添加到列表时 Control
重新绘制 ComboBox
。添加项目后,您可以使用ComboBox.EndUpdate()
重新绘制。
解决方案#2
private void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
}