制控件時,會觸發(fā)OnPaintBackground方法,繪制控件背景。然后觸發(fā) OnPaint()方法,繪制控件界面。當(dāng)繪制很慢的時候,會先看到背景,然后才看到界面,這樣就造成閃爍。解決方案:
1、在構(gòu)造函數(shù)中啟用雙緩沖(雙緩沖只適用于一個單一的控件,而不適用于一組復(fù)合控件。)
public test() { this.SetStyle( ControlStyles.UserPaint | //控件自行繪制,而不使用操作系統(tǒng)的繪制 ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,減少閃爍。 ControlStyles.OptimizedDoubleBuffer |//在緩沖區(qū)上繪制,不直接繪制到屏幕上,減少閃爍。 ControlStyles.ResizeRedraw | //控件大小發(fā)生變化時,重繪。 ControlStyles.SupportsTransparentBackColor, true);//支持透明背景顏色 }
注:當(dāng)控件中的子控件比較多時(稱為復(fù)合控件),此時窗體的繪制比較耗時,閃爍更為明顯,此時雙緩沖不起作用。解決方案:
2、設(shè)置CreateParams的ExStyle 為 0x02000000(WS_EX_COMPOSITED),會把窗體和它的子窗體都開啟雙緩沖。
protected override CreateParams CreateParams { get { CreateParams cp=base.CreateParams; cp.ExStyle |=0x02000000; return cp; } }
注:首先重寫CreateParams 方法可以有效解決任何閃爍的問題,但是在控件的的visiable屬性變化或者當(dāng)窗體從最小化還原時,窗體的顯示會出現(xiàn)問題。其次這種方式并不會加快繪制的過程,當(dāng)發(fā)生繪制時,窗體只是停留在不可見的狀態(tài),當(dāng)繪制完成后才顯示,這時窗體的輪廓是可見的,在繪制區(qū)域會出現(xiàn)一個黑色矩形框。解決方案:
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> /// 定時任務(wù) /// </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
注:若單獨使用第第三種方法,那么在顯示時效果比較好,但是在控件隱藏或者關(guān)閉的時候,閃爍還是比較明顯,此時需要用將第二種和第三種方法同時使用,即解決了第二種方法中出現(xiàn)的問題,也彌補了第三種方法中的不足。
C#的Windows Forms應(yīng)用程序中,制作一個閃爍的窗體通常涉及到改變窗體的背景色或標(biāo)題欄顏色,并使用Timer控件來控制顏色變化的頻率,從而創(chuàng)建閃爍效果。以下是一個簡單的示例,展示了如何制作一個閃爍的窗體:
首先,創(chuàng)建一個新的Windows Forms應(yīng)用程序項目,并添加一個Timer控件到你的窗體上。然后,設(shè)置窗體的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();
// 設(shè)置窗體的DoubleBuffered屬性為true,減少閃爍
this.DoubleBuffered=true;
// 初始化Timer
flashTimer=new Timer();
flashTimer.Interval=500; // 設(shè)置閃爍速度,這里是500毫秒
flashTimer.Tick +=new EventHandler(FlashTimer_Tick);
flashTimer.Start(); // 啟動Timer
}
private void FlashTimer_Tick(object sender, EventArgs e)
{
// 切換閃爍狀態(tài)
isFlashing=!isFlashing;
// 根據(jù)閃爍狀態(tài)改變窗體的背景色
if (isFlashing)
{
this.BackColor=flashColor;
}
else
{
this.BackColor=Color.White; // 或其他非閃爍顏色
}
}
}
在這個示例中,F(xiàn)lashTimer_Tick方法會在每次Timer觸發(fā)時被調(diào)用。這個方法會切換isFlashing變量的值,并根據(jù)這個值改變窗體的背景色。flashColor變量定義了閃爍時的顏色,你可以根據(jù)需要更改這個顏色。
請注意,設(shè)置窗體的DoubleBuffered屬性為true可以減少閃爍,但可能會引入其他問題,比如繪制問題。如果你的窗體包含復(fù)雜的自定義繪制邏輯,你可能需要實現(xiàn)自己的雙緩沖機(jī)制。
此外,如果你想要閃爍的是窗體的標(biāo)題欄,那么你可能需要更復(fù)雜的處理,因為標(biāo)題欄是由操作系統(tǒng)繪制的,不直接受窗體屬性的控制。在這種情況下,你可能需要調(diào)用Windows API或使用P/Invoke來實現(xiàn)這種效果。
C# Windows Forms應(yīng)用程序中,若要實現(xiàn)一個NotifyIcon控件(托盤圖標(biāo))像QQ一樣在任務(wù)欄閃爍,你需要使用一些額外的邏輯來控制圖標(biāo)的閃爍。NotifyIcon控件本身并不直接支持閃爍功能。以下是一個簡化的方法來實現(xiàn)這一效果:
下面是一個簡單的示例代碼:
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"), // 你的圖標(biāo)路徑
Visible=true,
ContextMenuStrip=new ContextMenuStrip(), // 可選:添加右鍵菜單
};
notifyIcon.MouseClick +=notifyIcon_MouseClick; // 可選:添加鼠標(biāo)點擊事件處理方法
}
private void InitializeTimer()
{
timer=new Timer();
timer.Interval=500; // 設(shè)置閃爍頻率,例如500毫秒(半秒)
timer.Tick +=Timer_Tick;
timer.Start(); // 開始計時器
}
private void Timer_Tick(object sender, EventArgs e)
{
if (random.Next(2)==0) // 50%的幾率顯示圖標(biāo),50%的幾率隱藏圖標(biāo)
{
notifyIcon.Visible=false; // 隱藏圖標(biāo)
}
else
{
notifyIcon.Visible=true; // 顯示圖標(biāo)
}
}
private void notifyIcon_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button==MouseButtons.Left) // 如果是左鍵點擊,則顯示主窗口(例如QQ的點擊效果)
{
this.Show(); // 顯示主窗口,或者根據(jù)需要執(zhí)行其他操作,如激活窗口等。
}
}
}
這段代碼創(chuàng)建了一個定時器,每隔500毫秒(半秒)就有一半的幾率隱藏或顯示通知圖標(biāo),從而產(chǎn)生閃爍的效果。記得替換"icon.ico"為你的實際圖標(biāo)文件路徑。如果需要實現(xiàn)更復(fù)雜的閃爍效果,例如QQ那樣的漸變閃爍,可能需要更復(fù)雜的邏輯或使用第三方庫來實現(xiàn)。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。