|
สำหรับบทความนี้แอดมินจะแสดงให้เห็นถึงการนำเอา CheckedListBox Control มาประยุกต์ใช้งานกับข้อมูล Initailize File หรือ INI สาระสำคัญคือ การแยก (Parser) ข้อมูลในตัว INI ซึ่งจะประกอบไปด้วย Section ตามด้วย Key และ Value เช่น
[test]
Item 1 = True
Item 2 = False
Item 3 = True
[language]
default=thai
เมื่อข้อมูลที่อยู่ในเครื่องหมาย Bracket [] คือ Section ส่วน Item 1 คือ Key และ True คือ Value ... โดยทั่วๆไปก็ไม่ค่อยมีปัญหามากมายนักกับการอ่านข้อมูลในแต่ละ Section ที่มีรูปแบบตายตัวเหมือนตัวอย่างด้านบน แต่บางครั้งปัญหาจะเกิดในลักษณะของการจัดเก็บข้อมูลในแบบ Dynamic ที่ทำให้เกิดความยืดหยุ่นของงานโปรแกรมมากกว่าแบบ Static ดังนั้นปัญหาของ INI Parser ก็คือในกรณีเราไม่รู้จุดสิ้นสุดของข้อมูลในแต่ละชุด ...
แอดมินก็พึ่งหัดใช้ CheckedListBox เป็นครั้งแรก ซึ่งการเริ่มต้นฝึกฝนของแอดมิน ก็จะก้าวข้ามส่วนของการ Design Time ไป แล้วมักจะใช้วิธีการเขียนโค้ดแบบ Run Time แทน เช่น โค้ดตัวอย่างนี้เป็นการสร้าง Item ขึ้นมาด้วยโค้ด และสุ่มค่าเลขคู่/คี่เพื่อกำหนด Checked/Unchecked ในแต่ละ Item
- ' / --------------------------------------------------------------------
- ' / สร้าง CheckedListBox และสุ่มค่า Check/Uncheck ทำการทดสอบ
- Private Sub CreateSample()
- Me.CheckedListBox1.Items.Clear()
- Dim RndClass As New Random
- For i As Integer = 0 To 14
- With Me.CheckedListBox1
- .Items.Add("Item " & i + 1)
- If RndClass.Next(0, 99) Mod 2 = 0 Then
- CheckedListBox1.SetItemChecked(i, CheckState.Checked)
- End If
- End With
- Next
- End Sub
คัดลอกไปที่คลิปบอร์ด
โค้ดในส่วนของการแยกแยะ Key กับ Value ออกจากกัน
- ' / --------------------------------------------------------------------
- ' / แยก Key และ Value เพื่อแสดงผลใน CheckedListBox
- Private Sub ParserCheckedListBox(ByVal iniFile As String, ByVal Section As String)
- Dim blnMatch As Boolean = False
- Dim iRow As Integer = 0
- '/ Reads each line from the text file one at a time.
- For Each line As String In IO.File.ReadLines(iniFile)
- '/ ต้องเช็คก่อนว่าเป็น Section ที่ต้องการหรือไม่? (ใส่ Lower Case หรือให้เป็นอักษรตัวเล็กทั้งหมด)
- If LCase(line) = "[" & LCase(Section) & "]" Then
- blnMatch = True
- '/ เมื่อได้ Section ตามที่ต้องการ (blnMatch = True)
- ElseIf blnMatch Then
- '/ แยก (Split) Key กับ Value ออกจากกันด้วยเครื่องหมาย =
- Dim sArr As String() = line.Split("="c)
- '/ เพิ่มไอเทมด้วย sArr(0)
- CheckedListBox1.Items.Add(sArr(0))
- '/ หากค่าใน sArr(1) มีค่าเป็นจริง (CBool = Convert To Boolean)
- If CBool(sArr(1)) Then CheckedListBox1.SetItemChecked(iRow, CheckState.Checked)
- '/ เลื่อน Key ไอเทม
- iRow += 1
- End If
- Next
- End Sub
คัดลอกไปที่คลิปบอร์ด แอดมินเขียนเป็นโปรแกรมย่อย (Sub Program) เอาไว้ให้เพียงเท่านี้ เพราะง่ายต่อการศึกษาโค้ดก่อน แต่ฝากคำถามให้ไปคิดกันต่อในเรื่องของการแยกข้อมูลออกจากกันของ INI ซึ่งมันเป็นงานเหมือนเดิมที่ซ้ำๆกันตลอด แต่ให้สังเกตว่าการนำ Key และ Value ไปใช้ใน Control แต่ละตัวมันจะมี Method ที่ไม่เหมือนกัน ตรงนี้แหละที่เราจะลดรูปคำสั่งลงด้วยวิธีการอย่างไร???
ตัวอย่างของการบันทึกไฟล์ INI ซึ่งในลักษณะไดนามิคแบบนี้ จะทำให้เราลดชุดคำสั่งลงไปในกรณีที่มีไอเทมเป็นจำนวนมากๆได้ - Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles btnSave.Click
- For i As Integer = 0 To Me.CheckedListBox1.Items.Count - 1
- WriteIni(strFileINI, "test", CheckedListBox1.Items(i), CheckedListBox1.GetItemChecked(i))
- Next
- MsgBox("Save data initialize complete.")
- Me.Close()
- End Sub
คัดลอกไปที่คลิปบอร์ด
โค้ดแบบเต็มทั้งหมด
- Public Class frmCheckedListBox
- Dim strFileINI As String = MyPath(Application.StartupPath) & "config.ini"
- Private Sub frmCheckedListBox_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
- '// เช็คว่ามีไฟล์ Config.ini อยู่หรือไม่???
- If My.Computer.FileSystem.FileExists(strFileINI) Then
- Call ParserCheckedListBox(strFileINI, "test")
- Else
- '/ การสร้างไอเทมและค่าแบบสุ่ม
- Call CreateSample()
- End If
- End Sub
- ' / --------------------------------------------------------------------
- ' / แยก Key และ Value เพื่อแสดงผลใน CheckedListBox
- Private Sub ParserCheckedListBox(ByVal iniFile As String, ByVal Section As String)
- Dim blnMatch As Boolean = False
- Dim iRow As Integer = 0
- '/ Reads each line from the text file one at a time.
- For Each line As String In IO.File.ReadLines(iniFile)
- '/ ต้องเช็คก่อนว่าเป็น Section ที่ต้องการหรือไม่? (ใส่ Lower Case หรือให้เป็นอักษรตัวเล็กทั้งหมด)
- If LCase(line) = "[" & LCase(Section) & "]" Then
- blnMatch = True
- '/ เมื่อได้ Section ตามที่ต้องการ (blnMatch = True)
- ElseIf blnMatch Then
- '/ แยก (Split) Key กับ Value ออกจากกันด้วยเครื่องหมาย =
- Dim sArr As String() = line.Split("="c)
- '/ เพิ่มไอเทมด้วย sArr(0)
- CheckedListBox1.Items.Add(sArr(0))
- '/ หากค่าใน sArr(1) มีค่าเป็นจริง (CBool = Convert To Boolean)
- If CBool(sArr(1)) Then CheckedListBox1.SetItemChecked(iRow, CheckState.Checked)
- '/ เลื่อน Key ไอเทม
- iRow += 1
- End If
- Next
- End Sub
- ' / --------------------------------------------------------------------
- Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles btnSave.Click
- For i As Integer = 0 To Me.CheckedListBox1.Items.Count - 1
- WriteIni(strFileINI, "test", CheckedListBox1.Items(i), CheckedListBox1.GetItemChecked(i))
- Next
- MsgBox("Save data initialize complete.")
- Me.Close()
- End Sub
- ' / --------------------------------------------------------------------
- ' / สร้าง CheckedListBox และสุ่มค่า Check/Uncheck ทำการทดสอบ
- Private Sub CreateSample()
- Me.CheckedListBox1.Items.Clear()
- Dim RndClass As New Random
- For i As Integer = 0 To 14
- With Me.CheckedListBox1
- .Items.Add("Item " & i + 1)
- If RndClass.Next(0, 99) Mod 2 = 0 Then
- CheckedListBox1.SetItemChecked(i, CheckState.Checked)
- End If
- End With
- Next
- End Sub
- Private Sub frmCheckedListBox_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
- Me.Dispose()
- Application.Exit()
- End Sub
- Private Sub btnExit_Click(sender As System.Object, e As System.EventArgs) Handles btnExit.Click
- Me.Close()
- End Sub
- End Class
คัดลอกไปที่คลิปบอร์ด
โค้ดในส่วนของ GetPrivateProfileString/WritePrivateProfileString หรือ Windows API ที่เรานำมาใช้กับ INI File
- Module modFunction
- ' / --------------------------------------------------------------------
- ' / Initialized Management
- Private Declare Unicode Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringW" ( _
- ByVal lpApplicationName As String, _
- ByVal lpKeyName As String, _
- ByVal lpString As String, _
- ByVal lpFileName As String _
- ) As Int32
- Private Declare Unicode Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringW" ( _
- ByVal lpApplicationName As String, _
- ByVal lpKeyName As String, _
- ByVal lpDefault As String, _
- ByVal lpReturnedString As String, _
- ByVal nSize As Int32, _
- ByVal lpFileName As String _
- ) As Int32
- ' / --------------------------------------------------------------------
- ' / --------------------------------------------------------------------
- Public Function WriteIni(ByVal iniFileName As String, ByVal Section As String, ByVal ParamName As String, ByVal ParamVal As String) As Integer
- WriteIni = WritePrivateProfileString(Section, ParamName, ParamVal, iniFileName)
- End Function
- ' / --------------------------------------------------------------------
- Public Function ReadIni(ByVal IniFileName As String, ByVal Section As String, ByVal ParamName As String, ByVal ParamDefault As String) As String
- Dim ParamVal As String = Space$(1024)
- Dim LenParamVal As Long = GetPrivateProfileString(Section, ParamName, ParamDefault, ParamVal, Len(ParamVal), IniFileName)
- ReadIni = Left$(ParamVal, LenParamVal)
- End Function
- ' / --------------------------------------------------------------------
- ' / Get my project path
- ' / AppPath = C:\My Project\bin\debug
- ' / Replace "\bin\debug" with ""
- ' / Return : C:\My Project\
- Function MyPath(ByVal AppPath As String) As String
- '/ MessageBox.Show(AppPath);
- AppPath = AppPath.ToLower()
- '/ Return Value
- MyPath = AppPath.Replace("\bin\debug", "").Replace("\bin\release", "").Replace("\bin\x86\debug", "")
- '// If not found folder then put the \ (BackSlash) at the end.
- If Microsoft.VisualBasic.Right(MyPath, 1) <> "" Then MyPath = MyPath & ""
- End Function
- End Module
คัดลอกไปที่คลิปบอร์ด
ดาวน์โหลดโค้ดฉบับเต็ม VB.NET (2010) ได้ที่นี่
|
ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง
คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน
x
|