C# GDI進行Button重繪
阿新 • • 發佈:2019-01-02
public partial class ButtonEx : Button { public ButtonEx() { //首先開啟雙緩衝,防止閃爍 //雙緩衝的一大堆設定 具體引數含義參照msdn的ControlStyles列舉值 this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.BackColor = Color.Transparent; } //用來標示是否滑鼠正在懸浮在按鈕上 true:懸浮在按鈕上 false:滑鼠離開了按鈕 private bool m_bMouseHover; //用來標示是否滑鼠點選了按鈕 true:按下了按鈕 false:鬆開了按鈕 private bool m_bMouseDown; //過載滑鼠懸浮的事件 protected override void OnMouseEnter(EventArgs e) { //當滑鼠進入控制元件時,標示變數為進入了控制元件 m_bMouseHover = true; //重新整理面板觸發OnPaint重繪 this.Invalidate(); base.OnMouseEnter(e); } //過載滑鼠離開的事件 protected override void OnMouseLeave(EventArgs e) { //當滑鼠離開控制元件時,標示變數為離開了控制元件 m_bMouseHover = false; //重新整理面板觸發OnPaint重繪 this.Invalidate(); base.OnMouseLeave(e); } //過載滑鼠按下的事件 protected override void OnMouseDown(MouseEventArgs mevent) { //當滑鼠按下控制元件時,標示變數為按下了控制元件 m_bMouseDown = true; //重新整理面板觸發OnPaint重繪 this.Invalidate(); base.OnMouseDown(mevent); } //過載滑鼠鬆開的事件 protected override void OnMouseUp(MouseEventArgs mevent) { //當滑鼠鬆開時,標示變數為按下並鬆開了控制元件 m_bMouseDown = false; //重新整理面板觸發OnPaint重繪 this.Invalidate(); base.OnMouseUp(mevent); } //過載繪畫事件 protected override void OnPaint(PaintEventArgs pevent) { base.OnPaint(pevent); //因為上面呼叫了base會繪製原生控制元件 重刷一下背景清掉原生繪製 不然自己繪製的是重疊在原生繪製上 base.OnPaintBackground(pevent); //得到繪畫控制代碼 Graphics g = pevent.Graphics; //定義字型格式 StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; //處理熱鍵 當Alt點下時 sf.HotkeyPrefix = this.ShowKeyboardCues ? HotkeyPrefix.Show : HotkeyPrefix.Hide; //判斷使用什麼資源圖 Bitmap bmpDraw = Properties.Resources.QBtn_Normal; //如果禁用了,則使用禁用時的樣式圖片繪製,否則呼叫其他滿足條件的樣式圖片繪製 if (!this.Enabled) bmpDraw = Properties.Resources.Qbtn_Gray; else if (m_bMouseDown) bmpDraw = Properties.Resources.QBtn_Down; else if (m_bMouseHover) bmpDraw = Properties.Resources.QBtn_High; else if (this.Focused) bmpDraw = Properties.Resources.QBtn_Focus; //繪製背景(若不知道這句啥意思 參照九宮切圖裡面的程式碼) RenderHelper.RenderBackground(g, bmpDraw, this.ClientRectangle); //如果禁用了 if (!this.Enabled) { //則繪製雙重陰影文字 g.DrawString(this.Text, this.Font, Brushes.White, this.ClientRectangle, sf); g.TranslateTransform(-1, -1);//左上移動一個單位座標系 g.DrawString(this.Text, this.Font, Brushes.DarkGray, this.ClientRectangle, sf); g.ResetTransform(); return; } //否則,預設繪製正常字型 using (SolidBrush sb = new SolidBrush(this.ForeColor)) { g.DrawString(this.Text, this.Font, sb, this.ClientRectangle, sf); } } }