Vb.net VB 2013将列表框所选项目传递给后台工作程序

Vb.net VB 2013将列表框所选项目传递给后台工作程序,vb.net,visual-studio-2013,arguments,backgroundworker,Vb.net,Visual Studio 2013,Arguments,Backgroundworker,我需要将表单控件中的数据传递给后台工作人员。我已经用文本框和列表框中的单个选定项完成了这项工作。请参阅下文: Public Class BackgroundWorkerArguments Public StartName1 As String End Class Private Sub RunButton1_Click(sender As Object, e As EventArgs) Handles RunButton1.Click Dim Arguments As B

我需要将表单控件中的数据传递给后台工作人员。我已经用文本框和列表框中的单个选定项完成了这项工作。请参阅下文:

Public Class BackgroundWorkerArguments

    Public StartName1 As String

End Class

Private Sub RunButton1_Click(sender As Object, e As EventArgs) Handles RunButton1.Click

    Dim Arguments As BackgroundWorkerArguments = New BackgroundWorkerArguments()

        Arguments.StartName1 = StartNameListBox.SelectedItem

End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

Dim Arguments As BackgroundWorkerArguments = CType(e.Argument, BackgroundWorkerArguments)

Dim StartName As String = Arguments.StartName1 

End Sub
Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
我想在一个循环中实现这一点,以添加所有listbox所选项目。我在按钮单击中尝试了此操作:

For Each s As String In StartNameListBox1.SelectedItems()

        Arguments.StartName1 = s

    Next
Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
为了在后台恢复,我尝试了:

Dim Arguments As BackgroundWorkerArguments = CType(e.Argument, BackgroundWorkerArguments)

    For Each s As String In Arguments.StartName1

        Dim StartName As String = s

    Next
Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
但是,它只返回一个字符。无论如何,我有一个循环,对于列表框中选中的每个文件夹名称,它会将这些文件夹拉上拉链。当我运行程序时,出现的zip是空的,最多只有一个字符。如果我只对一个选定项使用第一种方法,那么一切都很好。所以我不能走得太远!如果有人能告诉我正确的方向,请告诉我。谢谢

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
更新:

' Fills path of browsed folder into first text box.

    If (FolderBrowserDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
        StartPathTextBox1.Text = FolderBrowserDialog1.SelectedPath
        StartNameListBox1.Items.Clear()

        ' Fills foldernames within browsed folder into listbox.

        For Each s As String In System.IO.Directory.GetDirectories(StartPathTextBox1.Text)
            StartNameListBox1.Items.Add(IO.Path.GetFileName(s))
        Next
Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub

从MSDN:
中,必须小心不要操纵DoWork事件处理程序中的任何用户界面对象。相反,通过ProgressChanged和RunWorkerCompleted事件与用户界面通信。
有很多方法可以解决这个问题,但由于需要的主要UI访问是更新ProgressBar,ProgressChanged事件就足够了

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
还有一个更大的问题。BGW将使UI保持响应,这意味着用户可以在BGW中处理选定的编辑项时,从选定的编辑项中添加、更改或删除项目。在处理集合时,不能允许更改集合的内容,否则您的代码可能会用尽项或丢失项

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
也许更重要的是,依赖诸如文本框和列表框之类的UI控件会将代码逻辑不可避免地绑定到该表单,这使得在其他程序中移动和重用代码变得困难。您可以使用列表变量来存储要做的事情的列表,而不是使用
ListBox
。这将使用
列表(字符串)

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
然后执行加载文件的过程:

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
数据实际上在我们的
allFiles
列表变量中。使用它作为ListBox.Datasource可以在那里显示列表,而无需复制数据。如果您的代码要对列表进行许多更改,则可以使用
BindingList(Of T)
,这些更改将在更新时显示在UI中

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
请注意,如果您正在处理来自不同文件夹的文件,则需要类似FileClass的内容来存储每个文件的文件夹名称。自定义文件类和
列表(文件类)
将允许这种灵活性

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
目前,您正在切断路径,然后从用户可能已更改为无效位置的文本框将其重新粘贴。这会将文件夹保存到
zFolder
变量中并重用它

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
有几种方法可以处理该列表
SelectedItems
是一个有效的集合,在许多情况下可以用作待办事项列表。如前所述,如果您正在使用BackgroundWorker,则用户可以在您处理该集合时更改该集合,因此我们将这些项复制到新列表以防止出现这种情况。我没有使用第二个UI列表框,因为用户已经可以看到所选内容,所以它是多余的;此列表供我们使用:

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
zFiles = New List(Of String)

' harvest selected files
For Each o As Object In filesLB.SelectedItems
    ' Selected items contains Object, cast back
    ' to string for the List
    zFiles.Add(Path.Combine(zFolder, CType(o, String))
Next

' ToDo: Zip the files in that zFiles list.
要压缩的文件列表不在UI中,而是在变量中由我们控制

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub

最好的方法是创建一个
Zipper
类,其中所有与zip相关的过程都是
封装的
。实际上,它们很可能与表单代码以及可能所有的事件内过程混合在一起。一个
Zipper类
将把核心逻辑从UI中分离出来,通过将Zip类添加到该项目中,您可以更快地创建其他与Zip相关的程序。我们喜欢可重用的代码,这可能比BGW更值得花时间学习。在这种情况下,上面的
zFiles
可以是集合属性:

Private Sub Button1_Click(...etc

    ' clear datasource for when user selects a new folder
    filesLB.DataSource = Nothing

    Using fb As New FolderBrowserDialog
        ' use old name as starting point if set
        If String.IsNullOrEmpty(zFolder) Then
            zFolder = Environment.GetFolderPath(_
                   Environment.SpecialFolder.MyDocuments)
        End If
        fb.SelectedPath = zFolder 

        If fb.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit Sub

        zFolder = fb.SelectedPath

        ' display selection, but do not allow text edit           
        labelFolder.Text = zFolder 
    End Using

    zFiles.Clear()         ' clear the list from last time

    ' loop thru files
    For Each s As String In System.IO.Directory.GetFiles(zFolder)

        ' add to list
        allFiles.Add(IO.Path.GetFileName(s))
    Next

    ' set datasource of listbox to this list
    ' contents of myFiles will automagically appear
    filesLB.DataSource = allFiles

End Sub
Private Z AS New Zipper

'...
For Each o As Object In filesLB.SelectedItems

    Z.Files.Add(Path.Combine(zFolder, CType(o, String))

Next
Z.Zip          ' method to process indicated files

BGW通常用于执行需要一段时间的任务,而不是处理UI元素。如果您对项目使用
列表(字符串)
列表(myClass)
(或BindingList),并将其用作列表框的数据源,BGW可以处理列表以执行任何操作。如果列表中的内容发生更改,ProgressChanged事件可能会更新UI控件。从外观上看,您正在使用BGW来处理一件事(StartName1只是一件事)。@puropoix-Hi。程序中发生的事情是,一旦用户浏览到一个文件夹,列表框就会填充文件夹名称。我使用该列表使用zip类来压缩所选的每个项目。所以,当我描述要压缩的文件夹的路径以及将其压缩到哪里时,我使用这个列表收集文件夹名称。我可以使用所选项目生成BGW可以读取的另一个列表吗?从:
您必须小心不要操纵DoWork事件处理程序中的任何用户界面对象。相反,通过ProgressChanged和RunWorkerCompleted事件与用户界面通信。
此外,您不希望用户在处理UI时更改其在UI中的选择。使用一个变量,比如List@Plutonix谢谢你提供的额外信息。你提出了一个很好的观点。在任务期间,我已从用户处禁用“运行”按钮。当然,我可以对其余的项目做同样的操作,但我认为在你暗示的情况下,即仍然允许用户访问UI,但不影响正在进行的任何操作(而不是我刚才建议的操作,禁用所有操作)是最好的。这是一个更干净的想法,我会研究它。谢谢为列表框存储内容;一个基于文件的类,可能适用于您的taskHi,感谢您提供丰富的信息。我当然理解你关于从UI线程中删除我正在使用的输入的观点。我将采纳所有这些意见,并着手改进我的项目结构!我目前正在做的第一步中的按钮点击。第一次通过时,“文件夹浏览”会更新列表,然后更新列表框。第二遍