雖然 VB.net 可以直接使用 GIF or SWF 呈現動畫效果,但為了顯示的流暢(同步)和能建立動態的表單圖示,和方便一些細節的控制,這裡還是自己做一個控制來用。
1.首先要建立一組或多組連續的影格來用。
2.為了應用上的方便我先把一系列的影格圖片合併成一張圖,要用時再根據圖寬除以圖高來得到共有多少個影格。
3.下面是幾個例子
雖然 VB.net 可以直接使用 GIF or SWF 呈現動畫效果,但為了顯示的流暢(同步)和能建立動態的表單圖示,方便一些細節的控制,這裡還是自己做一個控制來用。
- 首先要建立一組或多組連續的影格來用。
- 為了應用上的方便我先把一系列的影格圖片合併成一張圖,要用時再根據圖寬除以圖高來得到共有多少個影格。
-
下面是幾個例子:
-
可以多做幾組放在專案的 Resource 裡面備用,並且為它們命名。
程式碼部分:
- 挑選一個合適的 Control 來繼承,因為要做的圖片輪播器所以選用 PictureBox 為父類別,並讓它支援背景透明。
- 加一個 Timer 做為控制換圖時間週期的參考。
-
建構式如下:
Public Sub New() MyBase.New() InitializeComponent() SetStyle(ControlStyles.SupportsTransparentBackColor, True) 初始化圖檔資源() MyBase.Size = _擷取大小 End Sub '---取出指定的圖檔並得到相關參數--- Sub 初始化圖檔資源() _圖檔名稱 = "_" & _現用圖案ID.ToString _圖檔映像 = CType(My.Resources.ResourceManager.GetObject(_圖檔名稱), Bitmap) _圖檔映像.MakeTransparent() _擷取大小 = New Size(_圖檔映像.Height, _圖檔映像.Height) _畫格總數 = _圖檔映像.Width \ _圖檔映像.Height Timer1.Enabled = True End Sub
-
切換影格的程式碼如下:
'---用 Timer 控制輪播影格--- Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick _當下畫格 = If(_當下畫格 < _畫格總數 - 1, _當下畫格 + 1, 0) 播放單格(_當下畫格) End Sub '---根據圖號從圖檔中取出對應的部分放到自己的 Image 屬性--- Sub 播放單格(Optional id As Integer = 0) MyBase.SizeMode = PictureBoxSizeMode.StretchImage Dim _擷取大小 = New Size(_圖檔映像.Height, _圖檔映像.Height) Dim 擷取位置 = New Point(id * _圖檔映像.Height, 0) Dim 矩形區域 = New Rectangle(擷取位置, _擷取大小) Dim 輸出圖樣 As Image = _圖檔映像.Clone(矩形區域, Imaging.PixelFormat.Format32bppArgb) RaiseEvent 圖像更新了(Me, CType(輸出圖樣, Bitmap)) MyBase.Image = 輸出圖樣 End Sub
-
屬性安排很陽春,只有選圖、設定速度,和一個讓外部得影格總數的 Integer:
#Region "---屬性---" <Description("選擇動態圖樣式"), Browsable(True), Category("外觀")> _ Public Property 設定圖形樣式() As 圖案樣式 Get Return _現用圖案ID End Get Set(value As 圖案樣式) _現用圖案ID = value 初始化圖檔資源() End Set End Property <Description("設定播放速度"), Browsable(True), Category("行為")> _ Public Property 播放速度() As Integer Get Return _播放速度 End Get Set(value As Integer) value = If(value < 1, 1, If(value > 500, 500, value)) _播放速度 = value Timer1.Interval = value Timer1.Enabled = True End Set End Property <Description("取得播放畫格總數"), Browsable(True), Category("行為")> _ Public ReadOnly Property 畫格總數() As Integer Get Return _畫格總數 End Get End Property #End Region
- 宣告部分建立一組列舉,名稱和資源裡面的各張圖同名。
-
另外加一個回呼的事件告訴父端圖檔已經更新了。
#Region "---宣告---" Public Enum 圖案樣式 下載_灰 下載_紅 下載_綠 下載_藍 水滴_白 水滴_紅 水滴_綠 水滴_藍 地球_灰 地球_綠 地球_藍 地球_藍灰 星星_深灰 星星_淺灰 星星_黃 風車_灰_直 風車_灰_彎 時針_黑_大 時針_黑_小 閃星_亮點 圓箭_藍 圓箭_雙藍 齒輪_灰 齒輪_棕 齒輪_黑 齒輪_綠 齒輪_藍 齒輪_雙輪 End Enum Private _預設圖示 As Image Private _現用圖案ID As 圖案樣式 = 圖案樣式.下載_紅 Private _播放速度 As Integer = 100 Private _現用圖像 As Bitmap Private _圖檔名稱 As String = "_" & _現用圖案ID.ToString Private _圖檔映像 As Bitmap = CType(My.Resources.ResourceManager.GetObject(_圖檔名稱), Bitmap) Private _擷取大小 As Size = New Size(_圖檔映像.Height, _圖檔映像.Height) Private _畫格總數 As Integer = _圖檔映像.Width \ _圖檔映像.Height Private _當下畫格 As Integer = 0 Public Shadows Event 圖像更新了(ByVal sender As Object, ByVal e As Bitmap) '---傳回呼叫端的事件--- #End Region
-
編輯階段的擷圖:
-
表單的程式碼就更簡化了:
<System.Runtime.InteropServices.DllImportAttribute("user32.dll")> _ Private Shared Function DestroyIcon(ByVal handle As IntPtr) As Boolean End Function Private Sub i_圖像更新了(sender As Object, e As System.Drawing.Bitmap) Handles i.圖像更新了 Dim HIcon As IntPtr = e.GetHicon() Dim newIcon As Icon = System.Drawing.Icon.FromHandle(HIcon) Me.Icon = newIcon DestroyIcon(newIcon.Handle) End Sub
-
效果影片(表單放了多個控制項,並選其一為 Icon):
- 專案原始碼下載。[]