How to find and update a matching control once a f

2019-09-03 05:30发布

I have written a WinForm project which displays a ListBox containing a list of file names. When the user clicks a submit button, the application dynamically loads and displays one PictureBox control for each file and then waits while they are processed. As PDF files are generated for each one, the matching PictureBox for that file needs to be updated to display an image.

Here's what I have so far:

Private Sub ButtonSubmit_Click(sender As System.Object, e As System.EventArgs) Handles ButtonSubmit.Click

    Dim x As Integer = 790
    Dim y As Integer = 91
    For i As Integer = 0 To ListBox1.Items.Count - 1

        Dim key As String = ListBox1.Items(i).ToString()

        'adds picturebox for as many listbox items added
        Dim MyPictureBox As New PictureBox()
        MyPictureBox.Name = "pic" + key
        MyPictureBox.Location = New Point(x, y)
        MyPictureBox.Size = New Size(12, 12)
        MyPictureBox.SizeMode = PictureBoxSizeMode.StretchImage
        Me.Controls.Add(MyPictureBox)
        MyPictureBox.Image = My.Resources.Warning1
        ToolTipSpooling.SetToolTip(MyPictureBox, "Creating PDF...")
        x += 0
        y += 13

    Next i

    Call CheckPDFs()

End Sub

Public Sub CheckPDFs()
    Dim ListboxTicketIDs = (From i In ListBox1.Items).ToArray()

    For Each Item In ListboxTicketIDs
        Dim ID = Item.ToString

        Dim Watcher As New FileSystemWatcher()
        Watcher.Path = "C:\Temp\"
        Watcher.NotifyFilter = (NotifyFilters.Attributes)
        Watcher.Filter = ID + ".pdf"

        AddHandler Watcher.Changed, AddressOf OnChanged

        Watcher.EnableRaisingEvents = True
    Next

End Sub

Private Sub OnChanged(source As Object, e As FileSystemEventArgs)

    Dim p As PictureBox = CType(Me.Controls("pic" + ListBox1.Items.ToString()), PictureBox)
    p.Image = My.Resources.Ok1

End Sub

I'm having trouble changing the PictureBox to a different picture once the item(s) listed in the listbox are present, based on the FileSystemWatcher. For instance, the files are not always created in the same order as they exist in the ListBox.

EDIT

Working code below.

Public Class Form1

Private WithEvents Watcher As FileSystemWatcher

Public Sub CheckPDFs()
    For i As Integer = 0 To ListBox1.Items.Count - 1
        Watcher = New FileSystemWatcher()
        Watcher.SynchronizingObject = Me
        Watcher.Path = "C:\Temp\"
        Watcher.NotifyFilter = NotifyFilters.Attributes
        Watcher.Filter = "*.pdf"

        Watcher.EnableRaisingEvents = True
    Next
End Sub

Private Sub Watcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles Watcher.Changed

    Dim key As String = Path.GetFileNameWithoutExtension(e.Name)
    Dim p As PictureBox = CType(Me.Controls("pic" + key), PictureBox)
    p.Image = My.Resources.Ok

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    ListBox1.Items.Add(TextBox1.Text)
    TextBox1.Text = ""

    Dim x As Integer = 5
    Dim y As Integer = 5
    For i As Integer = 0 To ListBox1.Items.Count - 1

        Dim key As String = ListBox1.Items(i).ToString()

        'adds picturebox for as many listbox items added
        Dim MyPictureBox As New PictureBox()
        MyPictureBox.Name = "pic" + key
        MyPictureBox.Location = New Point(x, y)
        MyPictureBox.Size = New Size(15, 15)
        MyPictureBox.SizeMode = PictureBoxSizeMode.StretchImage
        Me.Controls.Add(MyPictureBox)
        MyPictureBox.Image = My.Resources.Info
        x += 0
        y += 18

    Next i

    Call CheckPDFs()
End Sub

1条回答
我想做一个坏孩纸
2楼-- · 2019-09-03 05:34

First of all, you don't need to create multiple file watchers. You just need a single file watcher to watch for any changes to the folder. I would recommend declaring it as a private field at the top of your form using the WithEvents keyword so you don't have to worry about adding and removing event handlers.

Next, when the watcher raises the changed event, you can get the file name of the file that changed by looking at the properties of the event args object. You need to get the name of the file that changed and then use the file name as the key to finding the matching picture box control.

Public Class Form1
    Private WithEvents Watcher As FileSystemWatcher

    Public Sub CheckPDFs()
        Watcher = New FileSystemWatcher()
        Watcher.Path = "C:\Temp\"
        Watcher.NotifyFilter = NotifyFilters.Attributes
        Watcher.Filter = "*.pdf"
    End Sub

    Private Sub Watcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles Watcher.Changed
        Dim key As String = Path.GetFileNameWithoutExtension(e.Name)
        Dim p As PictureBox = CType(Me.Controls("pic" + key), PictureBox)
        p.Image = My.Resources.Ok1
    End Sub
End Class

However, since you say in a comment below that the file name will not be the same as the text in the listbox, but that it will merely start with that text, you could do something like this, instead:

Private Sub Watcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles Watcher.Changed
    Dim p As PictureBox = Nothing
    For Each item As Object In ListBox1.Items
        If e.Name.StartsWith(item.ToString()) Then
            p = CType(Me.Controls("pic" + item.ToString()), PictureBox)
            Exit For
        End If
    Next
    If p IsNot Nothing Then
        p.Image = My.Resources.Ok1
    End If
End Sub
查看更多
登录 后发表回答