thongkorn โพสต์ 2017-12-20 13:21:17

[VB.NET] โค้ดประยุกต์ใช้งาน CheckedListBox Control กับข้อมูลเท็กซ์ไฟล์แบบ INI (Initialize File)

http://www.g2gnet.com/webboard/images/VBNet/CheckedListBoxINI.png
สำหรับบทความนี้แอดมินจะแสดงให้เห็นถึงการนำเอา CheckedListBox Control มาประยุกต์ใช้งานกับข้อมูล Initailize File หรือ INI สาระสำคัญคือ การแยก (Parser) ข้อมูลในตัว INI ซึ่งจะประกอบไปด้วย Section ตามด้วย Key และ Value เช่น

Item 1 = True
Item 2 = False
Item 3 = True


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) ได้ที่นี่

MrDen โพสต์ 2017-12-21 13:09:14

ขอบพระคุณอย่างสูงครับ{:3_41:}

g2gsoftuser โพสต์ 2022-10-25 17:06:37

ขอบคุณครับ
หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] โค้ดประยุกต์ใช้งาน CheckedListBox Control กับข้อมูลเท็กซ์ไฟล์แบบ INI (Initialize File)