Adding nodes to treeview with Begin Invoke / Invoke

删除回忆录丶 提交于 2019-12-25 02:13:35

问题


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:

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 an error:

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.

On the following line:

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.

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.


回答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

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

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

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


来源:https://stackoverflow.com/questions/21864281/adding-nodes-to-treeview-with-begin-invoke-invoke

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!