c#面板製作教程2
Button控制元件的製作:
先來看看我們最終要做的效果圖(分別對應普通、懸停、按下時的狀態):
下面就開始正式做。首先讓我們新建一個控制元件庫專案,命名為QLFUI。如圖:
然後將預設的UserControl1重新命名為 Button。接下來,我們就要在這上面來做文章了。
先來稍稍設定一下,讓這個使用者控制元件看起來更像一個按鈕吧!
Button的
Size: 78,30
BackgroundImageLayout:Stretch
然後拖一個label控制元件到這個使用者控制元件上,並設定label1的屬性為
AutoSize:false ,
Dock:fill,
TextAlign:MiddleCenter,
BackColor: Transparent,
Font: 宋體, 9pt
這幾個屬性。好了,是不是開始像一個按鈕了呢?
哦,差點忘了最後還要將整個控制元件(BUTTON)的背景色設定為Trasparent透明色。因為如果不設定成透明色那麼透明的圖片下面就會顯示出button的背景色(預設灰色),不好看。好了,現在樣子的已經大概有了,接下來就是程式設計了。先貼程式碼,然後我一個一個解釋:
[DefaultEvent("Click")]
public partialclass Button: UserControl
{
#region 變數//三種不同狀態下的圖片
Image _moveImage =null;
Image _downImage =null;
#endregion#region 屬性
[Category("QLFSkinDll")]
public ImageNormalImage
{
get
{
return_normalImage;
}
set
{
_normalImage
}
}
[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,至此這個按鈕空間的美化就做好了看看效果吧!
作者:錢李峰
出處:http://www.cnblogs.com/qianlifeng/