跟我學做c#皮膚美化(二)
跟我學做c#皮膚美化(二)
--Button控件的制作
這一篇的QLFUI按鈕.zip
先來看看我們最終要做的效果圖(分別對應普通、懸停、按下時的狀態):



下面就開始正式做。首先讓我們新建一個控件庫項目,命名為QLFUI。如圖:

然后將默認的UserControl1重命名為 Button。接下來,我們就要在這上面來做文章了。
先來稍稍設置一下,讓這個用戶控件看起來更像一個按鈕吧!
Button的
Size: 78,30
BackgroundImageLayout:Stretch
然后拖一個label控件到這個用戶控件上,并設置label1的屬性為
AutoSize:false ,
Dock:fill,
TextAlign:MiddleCenter,
BackColor: Transparent,
Font: 宋體, 9pt
這幾個屬性。好了,是不是開始像一個按鈕了呢?

哦,差點忘了最后還要將整個控件(BUTTON)的背景色設置為Trasparent透明色。因為如果不設置成透明色那么透明的圖片下面就會顯示出button的背景色(默認灰色),不好看。好了,現在樣子的已經大概有了,接下來就是編程了。先貼代碼,然后我一個一個解釋:
代碼
public partialclass Button: UserControl
{
#region 變量
//三種不同狀態下的圖片
Image _normalImage =null;
Image _moveImage =null;
Image _downImage =null;
#endregion
#region 屬性
[Category("QLFSkinDll")]
public ImageNormalImage
{
get
{
return_normalImage;
}
set
{
_normalImage = value;
}
}
[Category("QLFSkinDll")]
public ImageDownImage
{
get{ return _downImage; }
set
{
_downImage = value;
}
}
[Category("QLFSkinDll")]
public ImageMoveImage
{
get{ return _moveImage; }
set
{
_moveImage = value;
}
}
[Category("QLFSkinDll")]
public stringCaption
{
get{ returnthis.label1.Text;} //控件運行時會自動運行get方法得到值
set
{
this.label1.Text= value;
}
}
#endregion
#region 構造函數
public Button()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
//默認的是自帶的圖片樣式,如果使用該按鈕則必須手工指定當前按鈕你想要的背景圖片
_normalImage = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"QLFUI.Res.button.btnnomal.bmp"));
_moveImage = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"QLFUI.Res.button.btnfore.bmp"));
_downImage = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"QLFUI.Res.button.btndown.bmp"));
MakeTransparent(_normalImage);
MakeTransparent(_moveImage);
MakeTransparent(_downImage);
InitializeComponent();
this.BackgroundImage= _normalImage;
}
#endregion
#region 輔助函數
private voidMakeTransparent(Image image)
{
Bitmapbitmap = image as Bitmap;
bitmap.MakeTransparent(Color.FromArgb(255, 0, 255));
}
#endregion
#region 事件
private voidlabel1_MouseEnter(object sender, EventArgs e)
{
this.BackgroundImage= _moveImage;
}
private voidlabel1_MouseDown(object sender, MouseEventArgs e)
{
this.BackgroundImage= _downImage;
}
private voidlabel1_MouseLeave(object sender, EventArgs e)
{
this.BackgroundImage= _normalImage;
}
private voidlabel1_MouseUp(object sender, MouseEventArgs e)
{
this.BackgroundImage= _normalImage;
}
private voidlabel1_Click(object sender, EventArgs e)
{
this.OnClick(e);
}
#endregion
}
先看第一句:
[DefaultEvent("Click")],這句話是什么意思呢?我們知道平常我們拖一個按鈕后,在設計模式下雙擊這個按鈕就會自動產生這個按鈕的Click事件。這個默認的Click事件從哪里來的呢,毫無疑問就是[DefaultEvent("Click")]這一句來設置的啦!這里默認的是Click事件,如果寫成[DefaultEvent("MouseEnter")]就是MouseEnter事件啦!
接下來的四句分別定義了按鈕三種不同狀態下的bitmap。
下面的四個屬性分別是三種不同狀態下Image的屬性和按鈕的文字屬性Caption,大家一看應該就明白。具體要解釋的就是[Category("QLFSkinDll")]。這句話的意思是將這些屬性分類,看個圖片大家就都明白了:以后在項目中設置屬性時,我們定義的屬性就自動分類在QLFSkinDll下面了。
接下來是構造函數:public Button(){}中的內容。
第一句是開始了窗體的雙緩沖。雙緩沖的意思就是現在內容中將圖像畫好了然后再顯示到界面上去。在c#中圖像一多最怕的就是圖像閃爍的問題,開啟了雙緩沖雖說不能完全避免圖像閃爍,但起碼也能有一定的效果,我們就先開著吧^ ^!
接下來的三句就是給三個狀態的圖像賦值了,這里我是把圖像嵌入進來了,并沒有放置在外部。要應用嵌入的資源分兩步走:第一步在項目中點擊圖片的屬性,然后將“生成操作”改為嵌入的資源。

第二步應用就是我們用到的代碼啦:Assembly.GetExecutingAssembly().GetManifestResourceStream(@"QLFUI.Res.button.btnnomal.bmp"),這句話前面的照寫,后面的路徑規則是“命名空間+文件夾名+你的文件名+文件名后綴”,當然如果你的文件直接放在項目下就沒有文件夾名了。聰明的大家應該明白吧?呵呵!其中我們要用到的文件大家可以從我給的項目例子中復制。接下來的MakeTransparent(_normalImage);MakeTransparent(_moveImage);MakeTransparent(_downImage);三句先不看,可以注釋掉,下面會講解它的作用的。
第八句InitializeComponent()是系統自帶的初始化控件一些代碼,我們不用去管它。最后一句this.BackgroundImage =_normalImage;就是設置按鈕的其實的圖片的樣子啦!
好啦,寫了這么久,咱們還是先來看看能運行出個什么樣子出來吧!看看目前的狀態下,它離我們的目標還差多遠!見圖:

從圖中我們可以看到明顯的一個問題,就是按鈕的邊緣有粉紅色。而且如果你也正好做到這里也會發現鼠標經過按鈕時,按鈕沒有任何反應(廢話,我們還什么都沒做呢)。
好了,接下來就有目標了,解決這兩個問題我們這個按鈕美化的就差不多了!
先來解決第一個問題,去掉粉紅色。我們需要用到Bitmap的一個函數MakeTransparent(Color),這個函數的作用是使指定的顏色對 Bitmap 透明。也就是說我們只要將這個函數的Color設置為我們需要去掉的粉紅色不就行了?!
繼續看代碼,我們先寫一個函數private void MakeTransparent(Imageimage),這個函數的作用就是將傳進來的圖片的指定的顏色進行透明處理。函數里就兩句話,第一句話先將Image轉為Bitmap。第二句話就是進行透明處理,這里的Color.FromArgb(255, 0, 255)就是我們要去的粉紅色啦。那什么時候進行去色呢?毫無疑問,當然是在給三種狀態賦值后緊接著就去色啦!所以我們在構造函數中的5,6,7句加上透明處理。(倒過來講這個作用,大家習慣不習慣呢?)好了,現在我們再來運行一下:看圖:

呵呵,正如預料的那樣,粉紅色沒有了(圖中的灰色其實是透明的,只要在另外一個項目中引用一下就知道了),第一個問題解決!
再來看第二個問題,要實現按鈕的變色肯定是跟鼠標的事件相關啦,比如說鼠標一進入按鈕的范圍之內我們就讓按鈕的背景改變,按下和離開按鈕的時候也響應的改變背景。所以我們用到這四個事件(注意,事件都是label1的事件,因為我們將label覆蓋在按鈕上,所以我們點擊的其實是label1):MouseEnter,MouseDown, MouseLeave, MouseUp。具體的事件里面執行的代碼也很簡單,就是更換按鈕的背景圖片。好了,讓我們再運行一下看看效果:

OK!兩個問題都解決了,我們的按鈕運行的好像也很正常!鼠標進入,移出,按下的時候也會變換背景!但是,如果你另外建一個項目,并雙擊產生點擊事件并編寫相應代碼時就會發現點擊事件沒作用了。多么郁悶的一件事情啊,點擊事件都沒作用了,我們還要這個按鈕干嘛啊!別急,讓我們來解決它。首先要明白的就是我們在其他項目中引用的這個的button控件的點擊事件是整個用戶控件的點擊事件(還記得我們在整個button類的上方設置了默認的點擊事件嗎?),而當我們去點擊按鈕時我們實際點擊的只是label1。問題很明了了,我們點擊的是label1,設置的卻是整個用戶控件的事件,當然觸發不了事件了。既然問題已經搞明白了,下面就去解決它。
繼續看代碼:
既然我們點擊的是label1那么我們就在label1的點擊事件中做文章,如代碼所示,我們在label1的點擊事件中觸發了整個類(this)的onclick事件,然后這個onclick會去找相應的類的click事件,就是我們在其他項目中直接雙擊的那個事件啦!
OK,至此這個按鈕空間的美化就做好了看看效果吧!


Button控件的制作,實現了一個變化的按鈕效果!

浙公網安備 33010602011771號