制控件时,会触发OnPaintBackground方法,绘制控件背景。然后触发 OnPaint()方法,绘制控件界面。当绘制很慢的时候,会先看到背景,然后才看到界面,这样就造成闪烁。解决方案:
1、在构造函数中启用双缓冲(双缓冲只适用于一个单一的控件,而不适用于一组复合控件。)
public test() { this.SetStyle( ControlStyles.UserPaint | //控件自行绘制,而不使用操作系统的绘制 ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,减少闪烁。 ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。 ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。 ControlStyles.SupportsTransparentBackColor, true);//支持透明背景颜色 }
注:当控件中的子控件比较多时(称为复合控件),此时窗体的绘制比较耗时,闪烁更为明显,此时双缓冲不起作用。解决方案:
2、设置CreateParams的ExStyle 为 0x02000000(WS_EX_COMPOSITED),会把窗体和它的子窗体都开启双缓冲。
protected override CreateParams CreateParams { get { CreateParams cp=base.CreateParams; cp.ExStyle |=0x02000000; return cp; } }
注:首先重写CreateParams 方法可以有效解决任何闪烁的问题,但是在控件的的visiable属性变化或者当窗体从最小化还原时,窗体的显示会出现问题。其次这种方式并不会加快绘制的过程,当发生绘制时,窗体只是停留在不可见的状态,当绘制完成后才显示,这时窗体的轮廓是可见的,在绘制区域会出现一个黑色矩形框。解决方案:
3、使用计时器来增加不透明度值,使其在绘制后可见,这样用户就不会看到黑色矩形
#region 启动闪烁问题 //背景透明度增加定时器 private static System.Windows.Forms.Timer startTimer=null; //闪烁form private static Form blinkForm=null; /// <summary> /// 启动解决闪烁定时器 /// </summary> public static void startTimerForBlink(Form form) { blinkForm=form; startTimer=new System.Windows.Forms.Timer(); startTimer.Interval=100; startTimer.Tick +=startTimer_Tick; blinkForm.Opacity=0; startTimer.Start(); } /// <summary> /// 定时任务 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void startTimer_Tick(object sender, EventArgs e) { if (blinkForm.Opacity >=1) { startTimer.Stop(); } else { blinkForm.Opacity +=1; } } #endregion
注:若单独使用第第三种方法,那么在显示时效果比较好,但是在控件隐藏或者关闭的时候,闪烁还是比较明显,此时需要用将第二种和第三种方法同时使用,即解决了第二种方法中出现的问题,也弥补了第三种方法中的不足。
C#的Windows Forms应用程序中,制作一个闪烁的窗体通常涉及到改变窗体的背景色或标题栏颜色,并使用Timer控件来控制颜色变化的频率,从而创建闪烁效果。以下是一个简单的示例,展示了如何制作一个闪烁的窗体:
首先,创建一个新的Windows Forms应用程序项目,并添加一个Timer控件到你的窗体上。然后,设置窗体的DoubleBuffered属性为true以改善闪烁效果。
csharpusing System;
using System.Drawing;
using System.Windows.Forms;
public partial class FlashingForm : Form
{
private Timer flashTimer;
private bool isFlashing=false;
private Color flashColor=Color.Red; // 闪烁颜色
public FlashingForm()
{
InitializeComponent();
// 设置窗体的DoubleBuffered属性为true,减少闪烁
this.DoubleBuffered=true;
// 初始化Timer
flashTimer=new Timer();
flashTimer.Interval=500; // 设置闪烁速度,这里是500毫秒
flashTimer.Tick +=new EventHandler(FlashTimer_Tick);
flashTimer.Start(); // 启动Timer
}
private void FlashTimer_Tick(object sender, EventArgs e)
{
// 切换闪烁状态
isFlashing=!isFlashing;
// 根据闪烁状态改变窗体的背景色
if (isFlashing)
{
this.BackColor=flashColor;
}
else
{
this.BackColor=Color.White; // 或其他非闪烁颜色
}
}
}
在这个示例中,FlashTimer_Tick方法会在每次Timer触发时被调用。这个方法会切换isFlashing变量的值,并根据这个值改变窗体的背景色。flashColor变量定义了闪烁时的颜色,你可以根据需要更改这个颜色。
请注意,设置窗体的DoubleBuffered属性为true可以减少闪烁,但可能会引入其他问题,比如绘制问题。如果你的窗体包含复杂的自定义绘制逻辑,你可能需要实现自己的双缓冲机制。
此外,如果你想要闪烁的是窗体的标题栏,那么你可能需要更复杂的处理,因为标题栏是由操作系统绘制的,不直接受窗体属性的控制。在这种情况下,你可能需要调用Windows API或使用P/Invoke来实现这种效果。
C# Windows Forms应用程序中,若要实现一个NotifyIcon控件(托盘图标)像QQ一样在任务栏闪烁,你需要使用一些额外的逻辑来控制图标的闪烁。NotifyIcon控件本身并不直接支持闪烁功能。以下是一个简化的方法来实现这一效果:
下面是一个简单的示例代码:
csharpusing System;
using System.Windows.Forms;
using System.Threading;
public partial class MainForm : Form
{
private NotifyIcon notifyIcon;
private Timer timer;
private Random random=new Random();
public MainForm()
{
InitializeComponent();
InitializeNotifyIcon();
InitializeTimer();
}
private void InitializeNotifyIcon()
{
notifyIcon=new NotifyIcon()
{
Icon=new Icon("icon.ico"), // 你的图标路径
Visible=true,
ContextMenuStrip=new ContextMenuStrip(), // 可选:添加右键菜单
};
notifyIcon.MouseClick +=notifyIcon_MouseClick; // 可选:添加鼠标点击事件处理方法
}
private void InitializeTimer()
{
timer=new Timer();
timer.Interval=500; // 设置闪烁频率,例如500毫秒(半秒)
timer.Tick +=Timer_Tick;
timer.Start(); // 开始计时器
}
private void Timer_Tick(object sender, EventArgs e)
{
if (random.Next(2)==0) // 50%的几率显示图标,50%的几率隐藏图标
{
notifyIcon.Visible=false; // 隐藏图标
}
else
{
notifyIcon.Visible=true; // 显示图标
}
}
private void notifyIcon_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button==MouseButtons.Left) // 如果是左键点击,则显示主窗口(例如QQ的点击效果)
{
this.Show(); // 显示主窗口,或者根据需要执行其他操作,如激活窗口等。
}
}
}
这段代码创建了一个定时器,每隔500毫秒(半秒)就有一半的几率隐藏或显示通知图标,从而产生闪烁的效果。记得替换"icon.ico"为你的实际图标文件路径。如果需要实现更复杂的闪烁效果,例如QQ那样的渐变闪烁,可能需要更复杂的逻辑或使用第三方库来实现。
*请认真填写需求信息,我们会在24小时内与您取得联系。