使用Begin Invoke / Invoke将节点添加到树视图

时间:2014-02-18 20:11:39

标签: vb.net winforms visual-studio-2012 invoke begininvoke

我一直在完成我的第一个项目,并且从那些人那里得到了很多有价值的帮助,但现在又被卡住了。

以下子用于在添加新数据时将TreeNodes添加到TreeView,不包括某些文件类型/名称:

Sub DirSearch(ByVal strDir As String, ByVal strPattern As String, ByVal tvParent As TreeNodeCollection)
    Dim f As String
    Dim e As String
    Dim tvNode As TreeNode
    Dim ext() As String = strPattern.Split("|"c)

    Try
    For Each d In Directory.GetDirectories(strDir)
        If (UCase(IO.Path.GetFileName(d)) <> "BACKUP") And (UCase(IO.Path.GetFileName(d)) <> "BARS") Then

            tvNode = tvParent.Add(IO.Path.GetFileName(d))
            For Each e In ext
                For Each f In Directory.GetFiles(d, e)
                    If (UCase(IO.Path.GetFileName(f)) <> "DATA.XLS") And (UCase(IO.Path.GetFileName(f)) <> "SPIRIT.XLSX") Then
                        tvNode.Nodes.Add(IO.Path.GetFileName(f))

                    End If
                Next
            Next
            DirSearch(d, strPattern, tvNode.Nodes)
        End If

    Next
    Catch ex As Exception
    MsgBox(ex.Message)
    End Try
End Sub

我现在收到错误:

  

正在从错误的线程调用正在对此控件执行的操作。使用Control.Invoke或Control.BeginInvoke对正确的线程进行Marshal来执行此操作。

在以下行中:

tvNode = tvParent.Add(IO.Path.GetFileName(d))

显然,我理解它与'线程'和BeginInvoke / Invoke的使用有关,但即使在阅读了关于错误的MSDN文档后,我也不知道从哪里开始。

如果我将文件添加到初始目录(也是文件系统观察程序的主题以监视新添加的内容),则只会发生此错误。

有人会非常友善地以外行的方式给我一个解释,以便我能够理解。

1 个答案:

答案 0 :(得分:1)

此代码在后台线程上运行,修改UI元素是非法的。 Invoke / BeginInvoke方法是调度一段代码以在UI线程上运行的方法,其中元素可以被修改。例如,您可以将代码更改为以下

Dim action As Action = Sub() tvNode.Nodes.Add(IO.Path.GetFileName(f))
tvNode.TreeView.Invoke(action)

此代码将获取名为action的委托实例,并在允许对tvNode进行编辑的UI线程上运行

修复之前的Add调用有点棘手,因为没有Control实例可以调用BeginInvoke。需要更新方法的签名以将Dim control as Control作为参数。如果您愿意,可以为该参数传递TreeView。一旦存在,第一个Add就可以这样改变

Dim outerAction As Action = Sub() tvNode = tvParent.Add(IO.Path.GetFileName(d))
control.Invoke(outerAction)