Search code examples
vb.netfilereaderstreamreaderprogrammatically-created

How to get specific line and value in line seperate with coma from text file


I want get value 1 in all line for get path string, and programmatically add cover to flowlayoutpanel.

in Resource/Game List.ini (from drag n drop)

Apex Legends,Resource/Cover/Apex Legends.jpg,Resource/Game Info/Apex Legends.txt
Fortnite,Resource/Cover/Fortnite.jpg,Resource/Game Info/Fortnite.txt
PUBG,Resource/Cover/PUBG.jpg,Resource/Game Info/PUBG.txt

here my code :

Private Sub LabelSetting_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LabelSetting.Click
        FlpAddItem.Controls.Clear()

        'I am confused in this part to get value 1 in all line for get path string
        'Directory.GetFiles(Path) will be replace with streamreader from lines(i) value 1

        Dim Path = '???
        Dim ImageX As Image = Nothing
        Dim x As Int32 = Directory.GetFiles(Path).Count - 1
        Dim Img(x) As PictureBox
        Dim ImgText(x) As Label
        Dim ImgPanel As Panel

        For i = 0 To Directory.GetFiles(Path).Count - 1
            ImgPanel = New Panel
            With ImgPanel
                .Width = 96
                .Height = 136
                .BackColor = Color.Transparent
            End With

            FlpAddItem.Controls.Add(ImgPanel) 'Add panel to the flowlayoutpanel

            ImgText(i) = New Label
            With ImgText(i)
                .Name = Directory.GetFiles(Path)(i).Replace(Path, "").Replace(".jpg", "").Replace(".png", "")
                .FlatStyle = FlatStyle.Popup
                .Width = 116
                .Height = 40
                .Padding = New Padding(0, 3, 0, 0)
                .TextAlign = ContentAlignment.TopCenter
                .Dock = DockStyle.Bottom
                .BackColor = Color.Transparent
                .ForeColor = Color.Black
            End With

            Img(i) = New PictureBox
            With Img(i)
                .Width = 96
                .Height = 96
                .Padding = New Padding(20, 20, 20, 20)
                .BackColor = Color.Transparent
                .BorderStyle = BorderStyle.FixedSingle
                .SizeMode = PictureBoxSizeMode.StretchImage
            End With
            ImgPanel.Controls.Add(Img(i)) 'Add the picturebox to the panel

            ImageX = Image.FromFile(Directory.GetFiles(Path)(i), True)
            Img(i).Image = Image.FromFile(Directory.GetFiles(Path)(i))
            ImgText(i).Text = Directory.GetFiles(Path)(i)
            ImgPanel.Controls.Add(ImgText(i))
        Next
End Sub

Solution

  • I suggest creating a class for the game name and path information

    Public Class GamePath
        Public Property GameName As String
        Property Path As String
    
        Public Overrides Function ToString() As String
            Return GameName
        End Function
    End Class
    

    I have overridden ToString, so that the game name will automatically be displayed in a ListBox.

    When loading the form, I read this information from the INI-file and set it as data source of a listbox, where you will be able to select a game.

    Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim games =
            From line In File.ReadLines(IniFilePath)
            Let parts = line.Split(","c)
            Select New GamePath With {.GameName = parts(0), .Path = parts(1)}
        GameListBox.DataSource = games.ToList()
        GameListBox.SelectedIndex = 0 'Select first game
    End Sub
    

    Note that it is easier to use File.ReadLines than a StreamReader. You will have to add Imports System.IO to the top of the code. Then we use the LINQ syntax to split each line at the comma and to create the game path information.

    The user selects a game in the ListBox and then clicks a button. You can get the file path information from the ListBox like this:

    Dim gamePath As GamePath = DirectCast(GameListBox.SelectedItem, GamePath)
    

    Then read the files only once and assign the result to a variable

    Dim files As String() = Directory.GetFiles(gamePath.Path)
    

    Get the file count

    Dim fileCount As Integer = files.Count
    

    The whole Click method:

    Private Sub StartGameButton_Click(sender As Object, e As EventArgs) Handles StartGameButton.Click
        FlpAddItem.Controls.Clear()
    
        Dim gamePath As GamePath = DirectCast(GameListBox.SelectedItem, GamePath)
        Dim files As String() = Directory.GetFiles(gamePath.Path)
        Dim fileCount As Integer = files.Count
    
        Dim ImageX As Image = Nothing
        Dim Img(fileCount) As PictureBox
        Dim ImgText(fileCount) As Label
        Dim ImgPanel As Panel
    
        For i = 0 To fileCount - 1
            Dim filePath = files(i)
            ImgPanel = New Panel
            With ImgPanel
                .Width = 96
                .Height = 136
                .BackColor = Color.Transparent
            End With
    
            FlpAddItem.Controls.Add(ImgPanel) 'Add panel to the flowlayoutpanel
    
            ImgText(i) = New Label
            With ImgText(i)
                .Name = System.IO.Path.GetFileNameWithoutExtension(filePath)
                .FlatStyle = FlatStyle.Popup
                .Width = 116
                .Height = 40
                .Padding = New Padding(0, 3, 0, 0)
                .TextAlign = ContentAlignment.TopCenter
                .Dock = DockStyle.Bottom
                .BackColor = Color.Transparent
                .ForeColor = Color.Black
            End With
    
            Img(i) = New PictureBox
            With Img(i)
                .Width = 96
                .Height = 96
                .Padding = New Padding(20, 20, 20, 20)
                .BackColor = Color.Transparent
                .BorderStyle = BorderStyle.FixedSingle
                .SizeMode = PictureBoxSizeMode.StretchImage
            End With
            ImgPanel.Controls.Add(Img(i)) 'Add the picturebox to the panel
    
            ImageX = Image.FromFile(filePath, True)
            Img(i).Image = Image.FromFile(filePath)
            ImgText(i).Text = filePath
            ImgPanel.Controls.Add(ImgText(i))
        Next
    End Sub
    

    Some details:

    In the For-loop you can get the path of an image file with

    Dim filePath = files(i)
    

    You can get the name of the image with

    .Name = System.IO.Path.GetFileNameWithoutExtension(filePath)
    

    This automatically removes the directory name and the extension.

    Later on, you don't call Directory.GetFiles again:

    ImageX = Image.FromFile(filePath, True)
    Img(i).Image = Image.FromFile(filePath)
    ImgText(i).Text = filePath
    

    If you only want to read the file paths into a list, you could write

    Dim games =
        (From line In File.ReadLines(IniFilePath)
         Select line.Split(","c)(1)).ToList()