一、前言
技術沒有先進與落後,只有合適與不合適。
本篇的自定義控制元件是:開關按鈕(SwitchButton)。
開關按鈕非常簡單,實現方式也多種多樣,比如常見的:使用兩張不同的按鈕圖片,代表開和關,然後在點選時切換這兩張圖片。
而本篇和前兩篇一脈相承,都是繼承Control,使用GDI+去實現。因為都是相同的原理,所以如果看過前兩篇的講解,自己就可以實現出來。
雖說簡單,但仍有可雕琢之處,在基本的實現外,我還會加入緩動效果,以達到更加自然的動畫效果。
關於緩動,可以檢視這兩篇文章:
相信看完的你,一定會有所收穫。
本文地址:https://www.cnblogs.com/lesliexin/p/13552662.html
二、前期分析
(一)為什麼需要開關按鈕?
“開關按鈕(SwitchButton)”雖然不常聽說,但是到處都可以見到它的身影,手機、電腦、網頁等等到處都有“開關按鈕”。
“開關按鈕”的基本樣式如下:
“開關按鈕”效果很直觀,使用也很方便,但是在WinForm中卻沒有提供該控制元件,所以便需要自己去實現“開關按鈕”。
(二)實現目標
1,外觀
基本外觀如下:
同時可以配合Label控制元件來進行提示:
2,功能和特點
(1)支援動畫效果
不是簡單的“開”、“關”兩個狀態生硬的切換,而是需要有相應的動畫效果,包括按鈕圓點位置的變化、顏色的變化。
同時為了使圓點的移動更加自然,需要使用緩動效果。
(2)支援修改顏色
可以修改“關”時的背景條顏色、“開”時的背景條顏色、按鈕圓點的顏色。
(3)支援修改按鈕圓點的大小和背景條的大小
比如將按鈕圓點調小一點,便可以實現類似Win10中開關按鈕的效果:
比如將背景條調細,便可以實現很特別的效果:
(三)技術分析
仍是使用GDI+去實現,其原理上就是在簡化版的LTrackBar上加一個圓點。
而動畫效果,就是改變圓點的位置和前景條的寬度。關於動畫效果的的實現原理可以參考《三角函式與緩入緩出動畫及C#實現(圖文講解)》
三、開始實現
(一)前期準備。
此處僅作提綱,具體操作見前篇。
新建類:LScrollBar.cs
新增繼承:Control(需要新增引用:System.Windows.Forms.dll)
修改可訪問性為:public
(二)新增屬性
1,”開“狀態時背景條顏色
此顏色是當開關按鈕代表”開“的時候背景條的顏色。
2,”關“狀態時背景條顏色
此顏色是當開關按鈕代表”關“的時候背景條的顏色。
3,按鈕圓點顏色
此顏色是按鈕圓點的顏色
4,背景條高度
背景條的高度即可以高於按鈕圓點,也可以低於按鈕圓點。
5,按鈕圓點高度
按鈕圓點高度(直徑)即可以高於背景條高度,也可以低於背景條高度。
因為“背景條高度”和“按鈕圓點高度”不一定誰高誰低,所以為了方便使用,將自動調整控制元件尺寸為兩者較高的一方。
6,圓點距左右兩側距離
當“背景條高度”大於“按鈕圓點高度”時,為了使按鈕圓點邊緣距背景條邊緣距離相等,所以需要通過此屬於去設定。
比如:背景條高度為24,圓點高度為20,那麼將本屬性設定為(24-20)/2=2,即可達到圓點邊緣距背景條邊緣距離相等。
7,”開“、”關“狀態
此狀態用於標識或設定開關按鈕的開關狀態。
(三)新增事件
對於開關按鈕而言,只需要一個事件,那就是開關狀態發生改變時所產生的事件。
其中事件資料如下:
(四)重寫方法
1,OnPaint
在本方法中,我們要畫三個:背景條、前景條、圓點。
2,OnMouseDown
本方法代表滑鼠點選了開關按鈕。在此方法中,我們要實現以下操作:改變開關狀態、啟動動畫效果。
而動畫效果的實現,是使用定時器,不斷改變位置,併發生重繪。
在動畫效果結束後,停止定時器,並觸發開關狀態改變事件:LSwitched。之所以在此處觸發事件而不是在OnMouseDown中觸發,是為了避免事件LSwitched的實現阻塞動畫效果的實現。
在定時器事件中,使用了《緩動公式整理(附:C#實現及WPF原版對比)》中所編譯的DLL,其呼叫的方法原始碼如下,不想引用該DLL可以直接使用下方程式碼代替。
(五)新增雙緩衝
為了避免重繪時閃爍,可在其建構函式中加上對雙緩衝的支援。
(六)新增預設事件
為了實現雙擊控制元件就自動實現僅有的一個事件,故新增預設事件。
四、效果演示
在Form上新增本控制元件:LSwitchButton,調整控制元件各個屬性,並在旁邊新增一Label。
雙擊本控制元件,在事件中輸入以下程式碼:
執行程式,即可見到以下效果:
五、調整優化
就像本文開篇所說那樣:雖然簡單,但仍可雕琢。在這裡,將會對開關控制元件進行調整和優化。
(一)圓點切邊優化
雖然乍看起來沒什麼問題,但是在某些情況下,會發現按鈕圓點下方會被切去一點。如下:
雖然實現邏輯上是沒有問題的,但是實際效果確有此偏差,所以在這裡我們需要手動去調整,將控制元件的高度多新增一個畫素,這樣就可以解決切邊問題了。
(二)多種緩動效果支援
即然在本例中已經引用了緩動DLL(見:《緩動公式整理(附:C#實現及WPF原版對比)》),那麼不妨使開關按鈕的動畫支援所有緩動效果。
1,新增緩動效果屬性
2,修改定時器事件,新增所有緩動效果支援
3,不同緩動效果開關按鈕演示
注:由於GIF錄製幀率的限制,下方的緩動演示效果比實際效果要差上很多。
(1),預設(Quartic)
(2),Back
(3),Bounce
六、結束語
本篇並沒有什麼複雜難懂的知識,更多的是對已掌握知識的運用,特別是對前篇《緩動公式整理(附:C#實現及WPF原版對比)》中的緩動效果的使用。
技術並沒有先進和落後,只有合適與不合適。
所以,對自己掌握的知識多抱有一些信心,盡情釋放自己的想像力,並在實踐中提升自己。
七、原始碼及工程下載
https://files.cnblogs.com/files/lesliexin/03,LSwitchButton.7z