C# 係統應用之透明罩MyOpaqueLayer實現360界麵陰影效果
在完成“個人電腦使用記錄清除軟件”中,我設計的winform界麵需要應用到類似於"360安全衛士"的透明罩效果,文章主要引述了如何使用自定義組件MyOpaqueLayer,並自定義類OpaqueCommand中定義顯示透明罩函數ShowOpaqueLayer和隱藏透明罩函數HideOpaqueLayer實現,同時如何對控件添加透明罩及遇到的問題.
一.自定義透明罩MyOpaqueLayer組件
(聲明:此段代碼引用自海華博客https://www.cnblogs.com/JuneZhang/archive/2012/07/06/2579215.html)
在添加透明罩控件\組件時,我的想法是"右鍵項目->添加->添加控件",但添加沒有成功,在網上也沒有講到該添加的基礎方法,由於以前也沒遇到過自定義控件的問題,所以隻好采取的方法是拖拽修改過MyOpaqueLayer.cs文件至項目中,具體代碼如下(含詳細注釋):
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
namespace MyOpaqueLayer
{
/*
* [ToolboxBitmap(typeof(MyOpaqueLayer))]
* 用於指定當把你做好的自定義控件添加到工具欄時,工具欄顯示的圖標。
* 正確寫法應該是
* [ToolboxBitmap(typeof(XXXXControl),"xxx.bmp")]
* 其中XXXXControl是你的自定義控件,"xxx.bmp"是你要用的圖標名稱。
*/
[ToolboxBitmap(typeof(MyOpaqueLayer))]
/// <summary>
/// 自定義控件:透明罩控件(繼承Control)
/// </summary>
public class MyOpaqueLayer : System.Windows.Forms.Control
{
private bool _transparentBG = true; //是否使用透明
private int _alpha = 125; //設置透明度
private System.ComponentModel.Container components = new System.ComponentModel.Container();
public MyOpaqueLayer()
: this(125, true)
{
}
public MyOpaqueLayer(int Alpha, bool IsShowLoadingImage)
{
SetStyle(System.Windows.Forms.ControlStyles.Opaque, true); //設置控件樣式
base.CreateControl(); //創建控件
this._alpha = Alpha;
//放置加載進度的圖片代碼此處被省略
}
//釋放組件占用內存
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (!((components == null)))
{
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// 自定義繪製窗體
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
float vlblControlWidth;
float vlblControlHeight;
Pen labelBorderPen; //定義Pen
SolidBrush labelBackColorBrush; //定義單色畫筆
if (_transparentBG) //使用透明
{
Color drawColor = Color.FromArgb(this._alpha, this.BackColor);
labelBorderPen = new Pen(drawColor, 0);
labelBackColorBrush = new SolidBrush(drawColor);
}
else
{
labelBorderPen = new Pen(this.BackColor, 0);
labelBackColorBrush = new SolidBrush(this.BackColor);
}
base.OnPaint(e);
vlblControlWidth = this.Size.Width;
vlblControlHeight = this.Size.Height;
e.Graphics.DrawRectangle(labelBorderPen, 0, 0, vlblControlWidth, vlblControlHeight);
e.Graphics.FillRectangle(labelBackColorBrush, 0, 0, vlblControlWidth, vlblControlHeight);
}
//獲取創建控件句柄時所需要的創建參數
protected override CreateParams CreateParams //v1.10
{
get
{
CreateParams cp = base.CreateParams; //擴展派生類CreateParams屬性
cp.ExStyle |= 0x00000020; //開啟WS_EX_TRANSPARENT,使控件支持透明
return cp;
}
}
/*
* [Category("myOpaqueLayer"), Description("是否使用透明,默認為True")]
* 一般用於說明你自定義控件的屬性(Property)
* Category用於說明該屬性屬於哪個分類,Description自然就是該屬性的含義解釋。
*/
[Category("MyOpaqueLayer"), Description("是否使用透明,默認為True")]
public bool TransparentBG
{
get
{
return _transparentBG;
}
set
{
_transparentBG = value;
this.Invalidate();
}
}
//設置透明度
[Category("MyOpaqueLayer"), Description("設置透明度")]
public int Alpha
{
get
{
return _alpha;
}
set
{
_alpha = value;
this.Invalidate();
}
}
//初始化窗體
private void InitializeComponent()
{
this.SuspendLayout(); //臨時掛起控件的布局邏輯,它與ResumeLayout()配合使用
this.ResumeLayout(false); //恢複正常邏輯
}
}
}
二.自定義透明罩類OpaqueCommand
在第一部分我們已經自定義透明罩組件,此時需要自定義類OpaqueCommand並調用其方法ShowOpaqueLayer(顯示遮罩層)和HideOpaqueLayer(隱藏遮罩層).可以在“解決方法”中右鍵項目名->添加->類,具體代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EMSecure
{
class OpaqueCommand
{
//透明罩
private MyOpaqueLayer.MyOpaqueLayer m_OpaqueLayer = null;
/// <summary>
/// 顯示透明層
/// </summary>
/// <param name="control">控件</param>
/// <param name="alpha">透明度</param>
/// <param name="isShowLoadingImage">是否顯示圖標</param>
public void ShowOpaqueLayer(Control control, int alpha, bool isShowLoadingImage)
{
try
{
if (this.m_OpaqueLayer == null)
{
this.m_OpaqueLayer = new MyOpaqueLayer.MyOpaqueLayer(alpha, isShowLoadingImage);
control.Controls.Add(this.m_OpaqueLayer);
this.m_OpaqueLayer.Dock = DockStyle.Fill;
this.m_OpaqueLayer.BringToFront();
}
this.m_OpaqueLayer.Enabled = true;
this.m_OpaqueLayer.Visible = true;
}
catch (Exception msg) //異常處理
{
MessageBox.Show(msg.Message);
}
}
/// <summary>
/// 隱藏透明層
/// </summary>
public void HideOpaqueLayer()
{
try
{
if (this.m_OpaqueLayer != null)
{
this.m_OpaqueLayer.Visible = false;
this.m_OpaqueLayer.Enabled = false;
}
}
catch (Exception msg) //異常處理
{
MessageBox.Show(msg.Message);
}
}
}
}
三.使用透明罩
在定義透明罩控件和類後,如何實現該界麵的效果,我推薦的方法是:
1.設置toolBar控件,在items(集合)中添加相應的圖標\文字構成不同的ToolItem,每次透明罩遮掩不同的Item即可,如果是wfp使用TabControl\TabItem.但由於toolBar被toolStrip替代,不太會使用該控件,但仍然推薦該方法(有的沒有定義透明罩控件,而是通過3張透明程度不同的圖,設置可見屬性實現該效果).運行結果:
2.在代碼設計器Form中添加MyOpaqueLayer控件,此時就能看見6個透明罩的MyOpaqueLayer控件,該方法不需要設置自定義類OpaqueCommand調用其方法,而是設置如下代碼:
//鼠標離開
private void myOpaqueLayer1_MouseLeave(object sender, EventArgs e)
{
this.myOpaqueLayer1.Visible = false;
this.label4.ForeColor = Color.White;
}
//鼠標進入
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
this.myOpaqueLayer1.Visible = true;
this.label4.ForeColor = Color.Yellow;
}
設計器中form如下圖所示:
但由於不知道如何添加該控件拖動至設計器中,所以我采取的方法是
3.自定義6個panel,通過鼠標事件進入panelmol1_MouseEnter(object sender, EventArgs e)\鼠標離開事件panelmol1_MouseLeave(object sender, EventArgs e)\鼠標點擊事件panelmol1_MouseClick(object sender, EventArgs e)實現,最後我的運行結果如下圖所示:
下麵隻給出使用透明罩控件和類的基本調用代碼並省略Click部分(因為做的不是很好),請讀者體會與自己設計:
//自定義類OpaqueCommand
OpaqueCommand cmd = new OpaqueCommand();
//定義點擊panel時透明罩情況
bool isClick = false;
//鼠標進入"清除IE"
private void panel_mol1_MouseEnter(object sender, EventArgs e)
{
//透明罩設置 沒點擊才取消透明罩
cmd.ShowOpaqueLayer(panel_mol1, 125, true);
}
private void panel_mol1_MouseEnter(object sender, EventArgs e)
{
cmd.HideOpaqueLayer();
}
四.總結
個人感覺該設計還有很多地方需要自己改進,同時想實現ToolBar方法和了解如何添加自定義組件而不是拖拽,期望自己能解決這些問題.希望該文章對大家有所幫助,同時感謝下麵3篇文章及博主,是講述透明罩和如何自定義控件的文章,個人感覺非常不錯.如果文章中有不足或錯誤的地方,請海涵!
(By:Eastmount 2014-3-10 中午2點 原創:https://blog.csdn.net/eastmount)
參考資料及在線筆記:
1.C#實現Winform自定義半透明遮罩層-海華(主要參考透明罩的設定)
https://www.cnblogs.com/JuneZhang/archive/2012/07/06/2579215.html
2.C#中自定義控件-楊友山(自定義控件簡述)
https://blog.csdn.net/yysyangyangyangshan/article/details/7078471
3.C#自定義控件開發-百度文庫(詳細介紹自定義控件\複合控件\擴展控件)
https://wenku.baidu.com/view/89a47f6e58fafab069dc02bf.html
最後更新:2017-04-03 12:55:33