[WM]利用Microsoft.Drawing擴充Graphics & 製作自己的"option" form

這篇接著繼續說明Microsoft.Control.dll的功能,同樣的,如果看官還不知道要怎麼加入的話,可以參考之前的[WM]利用Microsoft.Drawing擴充Graphics & 製作我的按鈕這篇文章。
首先今天會使用到的是Graphics.DrawAlpha這個功能,Graphics.DrawAlpha可以繪製半透明的效果,例如下面的程式碼
Dim gOff As Graphics = Graphics.FromImage(_bmpOff)
''清除原先的圖形
gOff.Clear(Color.Black)
''繪圖動作
''繪製具透明度的背景
e.Graphics.DrawAlpha(_bmpOff, _Opacity, 0, 0)

其中_bmpOff是一個與Form同樣大小的bitamp,取得bitmap的Graphics之後,會先用黑色去清除整個bitmap;而為什麼是黑色?不是白色、藍色...這邊到沒有限定要用什麼顏色,只是黑色套用半透明後會有感覺像"lightbox"的效果就是了。接下來DrawAlpha的第一個參數是要繪製的圖形,第二個是透明度,255是完全不透明,0則是完全透明,第三、第四個參數就是要繪製的位置了。用這樣就可以簡單的繪製出半透明的效果;有一個部分要特別注意,如果繪製時要"透過去",看到下一層的東西,那麼就要複寫掉OnPaintBackground的事件,讓背景繪製不要發生,不然就會變成"一張有透明效果的圖,畫在白色(背景色)上"。
接下來就來看看今天測試的程式碼,筆者這邊是繼承Form的類別,來做一個可以設定透明度的Form就姑且稱做myForm吧(myPhone..?),之後在myForm上面放了3個myButton來做選擇的功能,選擇後會自行把Form關閉,並且將相關的資訊儲存在property中,程式碼會像下面這樣
Imports Microsoft.Drawing

Public Class myForm
Inherits Windows.Forms.Form

Private _bmpOff As Bitmap
Private _Opacity As Byte = 175
''儲存圖形
Private _imgList As ImageList
''自訂Form的回應情形
Private _Result As myFormResult = myFormResult.Ignore

Public Enum myFormResult As Integer
Ignore = 0
Option1 = 1
Option2 = 2
Option3 = 3
End Enum

#Region "Property"
'''
''' 設定背景透明度(255:不透明,0:全透明)
'''

'''
'''
'''
Public Property [Opacity]() As Byte
Get
Return _Opacity
End Get
Set(ByVal value As Byte)
_Opacity = value
End Set
End Property

'''
''' 自行定義的回應狀態
'''

'''
'''
'''
Public ReadOnly Property CustomResult() As myFormResult
Get
Return _Result
End Get
End Property

'''
''' 設定要繪製在畫面上的圖形
'''

'''
'''
'''
Public ReadOnly Property ImageItem() As ImageList.ImageCollection
Get
Return _imgList.Images
End Get
End Property
#End Region

'''
''' 直接點選Form的其他位置視為取消選擇的動作
'''

'''
'''
Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
''設定回傳訊息是忽略
Me.DialogResult = Windows.Forms.DialogResult.Ignore
Me.Close()
End Sub

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
If _bmpOff Is Nothing Then
_bmpOff = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height)
End If
Dim gOff As Graphics = Graphics.FromImage(_bmpOff)
''清除原先的圖形
gOff.Clear(Color.Black)
''繪圖動作
''繪製具透明度的背景
e.Graphics.DrawAlpha(_bmpOff, _Opacity, 0, 0)
''繪製其他圖形
If _imgList.Images.Count > 0 Then
Dim rect As New Rectangle
rect.Size = _imgList.Images(0).Size
For i As Integer = 0 To _imgList.Images.Count - 1
rect.X = (Me.ClientSize.Width \ _imgList.Images.Count \ 2) + (32 * (i Mod 4) + (i * 20))
''如果要位置在接近置中的地方
''rect.Y = (Me.ClientSize.Height - 32) \ 2
rect.Y = 20
e.Graphics.DrawImageTransparent(_imgList.Images(i), rect)
Next
End If
'release resource
gOff.Dispose()
'MyBase.OnPaint(e)
End Sub

'''
''' 一定要複寫才能有透過去的效果
'''

'''
'''
Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
''不要繪製背景
''MyBase.OnPaintBackground(e)
End Sub

''設定回應狀態
Private Sub MyButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyButton1.Click
_Result = myFormResult.Option1
Me.Close()
End Sub

''設定回應狀態
Private Sub MyButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyButton2.Click
_Result = myFormResult.Option2
Me.Close()
End Sub

''設定回應狀態
Private Sub MyButton3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyButton3.Click
_Result = myFormResult.Option3
Me.Close()
End Sub
End Class

而在"new"的部分,筆者也加了初始化的動作,像是下面這樣
 _
Public Sub New()
MyBase.New()

'此為元件設計工具所需的呼叫。
InitializeComponent()
''無邊框
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
''設定為最大化
Me.WindowState = FormWindowState.Maximized
''
_imgList = New ImageList
_imgList.ImageSize = New Size(32, 32)
End Sub

呼叫的時候大概會像下面這樣子
Dim f As New myForm
f.ImageItem.Add(New Bitmap("\Storage Card\1.png"))
f.ImageItem.Add(New Bitmap("\Storage Card\2.png"))
f.ImageItem.Add(New Bitmap("\Storage Card\3.png"))
f.ImageItem.Add(New Bitmap("\Storage Card\4.png"))
f.ShowDialog()
Select Case f.CustomResult
Case Is = myForm.myFormResult.Option1
TextBox1.Text = "button1 selected"
Case Is = myForm.myFormResult.Option2
TextBox1.Text = "button2 selected"
Case Is = myForm.myFormResult.Option3
TextBox1.Text = "button3 selected"
Case Else
TextBox1.Text = "nothing"
End Select
f.Dispose()

執行時,呼叫出自訂的form大致會像下面這樣

選擇某個按鈕後可以將選擇的值放置在屬性中讓呼叫的form去讀取,大致像下圖

留言

這個網誌中的熱門文章

開啟cshtml檔案時,出現『並未將物件參考設定為物件執行個體』的錯誤訊息

無法設定中斷點 尚未載入符號檔

DataGridView欄位計算總合