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

时间:2022-08-27 21:25:07

I've been working through my first project and have had a great deal a valuable help from the guys on SO but now I'm stuck again...

我一直在完成我的第一个项目,并且从那些人那里获得了很多有价值的帮助,但现在我再次陷入困境......

The below sub is used to add treenodes to a treeview, excluding certain filetypes/names, upon addition of new data

以下子用于在添加新数据时将treenode添加到树视图中,不包括某些文件类型/名称

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

I'm now getting a Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action. error on the following line

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

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

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

Obviously i understand its to do with 'threading' and the use of BeginInvoke/Invoke but even after reading the MSDN documentation on the error I have no idea where to start.

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

This error only occurs if i add a file to the initial directory (which is also the subject of a File System Watcher to monitor new additions).

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

Would someone be so kind as to give me an explanation in layman's terms so I may be able to understand.

有人会非常友好地以外行的方式给我一个解释,这样我才能理解。

Thanks :)

谢谢 :)

1 个解决方案

#1


1  

This code is being run on a background thread where it's illegal to modify UI elements. The Invoke / BeginInvoke methods are ways to schedule a piece of code to run on UI thread where elements can be modified. For example you could change your code to the following

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

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

This code will take the delegate instance named action and run it on the UI thread where edits to tvNode are allowed

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

Fixing the earlier Add call is a bit trickier because there is no Control instance on which we can call BeginInvoke. The signature of the method will need to be updated to take a Dim control as Control as a parameter. You can pass in the TreeView for that parameter if you like. Once that is present the first Add can be changed as such

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

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

#1


1  

This code is being run on a background thread where it's illegal to modify UI elements. The Invoke / BeginInvoke methods are ways to schedule a piece of code to run on UI thread where elements can be modified. For example you could change your code to the following

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

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

This code will take the delegate instance named action and run it on the UI thread where edits to tvNode are allowed

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

Fixing the earlier Add call is a bit trickier because there is no Control instance on which we can call BeginInvoke. The signature of the method will need to be updated to take a Dim control as Control as a parameter. You can pass in the TreeView for that parameter if you like. Once that is present the first Add can be changed as such

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

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