Assigning TreeView Class Instance to a TreeView Control

Assigning TreeView Class Instance to a TreeView Control

Post by TG9yZW » Fri, 11 Apr 2008 12:16:24


I have a TreeView population routine that is rather lengthy and have decided
to use a BackgroundWorker to run it in a background thread. Since I am
unable to access my TreeView control directly in the BackgroundWorker, I
create a new instance of a TreeView class in the background thread, populate
it, and then return it to my main thread through the e.Result
DoWorkEventArgs. All of this works fine.

My question is how do I assign this populated TreeView class instance to the
TreeView Control on my form? When I set my TreeView control to the populated
TreeView class instance nothing is displayed in the control. I have verified
that the nodes in the TreeView contain data. Any suggestion that anyone
might have would be appreciated.

--
Loren Baker
 
 
 

Assigning TreeView Class Instance to a TreeView Control

Post by Steve Gerr » Fri, 11 Apr 2008 14:46:26


I had to read that last part a few times myself. It can be confusing. ;)

Lets say the TreeView on your form is called myTreeView. You are doing something
like
myTreeView = CType(e.Result, TreeView)
and wonder why that doesn't put the new tree view on your form.

The thing is, myTreeView is just a reference variable, pointing to a TreeView.
It starts out pointing to the one created on your form. After a line like the
one above, it points to the one you created in your worker thread. But the one
on the form is still there, it just isn't being pointed to by your myTreeView
variable anymore. And the new one is not on the form; you would have to put it
there. Clear as mud?

If you look in the form designer.vb code, you will see something like
MyForm.Controls.Add (myTreeView)
which actually puts the control in the forms control collection. There will also
be a lot of properties set, such as size, position, and so on. You would need to
remove the TreeView that is in the form's controls collection, and add your new
one to it, transferring all the settings from the old one to the new one.

Is there anyway to just get a collection of Nodes back, and assign that to the
TreeView?

 
 
 

Assigning TreeView Class Instance to a TreeView Control

Post by Jack Jacks » Fri, 11 Apr 2008 15:22:24

On Wed, 9 Apr 2008 22:46:26 -0700, "Steve Gerrard"




If you create the new Treeview in another thread, is it legal to then
add that control to the form and access it from the UI thread?
 
 
 

Assigning TreeView Class Instance to a TreeView Control

Post by Steve Gerr » Fri, 11 Apr 2008 16:17:33


Good question, I'm not really sure. It seems like it should be okay, as long as
nothing UI related happens before you get it back to the UI thread and add it to
the form. At that point, all code will be running in the UI thread, and the
memory itself is okay since it is all the same process.
 
 
 

Assigning TreeView Class Instance to a TreeView Control

Post by TG9yZW » Sat, 12 Apr 2008 00:40:01

teve thanks for your reply. You understood my problem exactly 鈥?even right
down to myTreeView = CType(e.Result, TreeView) code.

I tried to assign the Nodes collection to the TreeView control, but it鈥檚
read only. But your other suggestion seems to work.

To simplify my problem and to test your suggested solution I created a new
test project with a TreeView control and three buttons. (See the code
below.) btnStart creates a simple test tree using the myTreeViewControl.
btnStartCreateNewTV creates the same test tree except it uses a new TreeView
class instance. btnAddNewChildNode adds a new child and grandchild node to
TreeView control, and seems to work with both ways of creating the test tree.

To address Jack鈥檚 concern about creating a the new Treeview in another
thread while the user might change the content of the TreeView control, I鈥檝e
disabled the TreeView control before starting the background thread.

Thanks again for you help.

Public Class Form1

Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnStart.Click
myTreeViewControl.Nodes.Clear()
Dim newNode As TreeNode

newNode = New TreeNode("Root Node 0")
myTreeViewControl.Nodes.Add(newNode)

Dim rootNode As TreeNode = myTreeViewControl.Nodes(0)
For i As Integer = 0 To 3
newNode = New TreeNode("Child Node 0" & i.ToString)
rootNode.Nodes.Add(newNode)
Next i

Dim childNode02 As TreeNode = myTreeViewControl.Nodes(0).Nodes(2)
For i As Integer = 0 To 3
newNode = New TreeNode("Grandchild Node 02" & i.ToString)
childNode02.Nodes.Add(newNode)
Next i

End Sub

Private Sub btnStartCreateNewTV_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnStartCreateNewTV.Click
myTreeViewControl.Enabled = False

Dim newTreeView As TreeView = New TreeView

Dim newNode As TreeNode

newNode = New TreeNode("Root Node 0")
newTreeView.Nodes.Add(newNode)

Dim rootNode As TreeNode = newTreeView.Nodes(0)
For i As Integer = 0 To 3
newNode = New TreeNode("Child Node 0" & i.ToString)
rootNode.Nodes.Add(newNode)
Next i

Dim childNode02 As TreeNode = newTreeView.Nodes(0).Nodes(2)
For i As Integer = 0 To 3
newNode = New TreeNode("Grandchild Node 02" & i.ToString)
childNode02.Nodes.Add(newNode)
Next i

' Remove myTreeViewControl from the form
' and add the newTreeView to the form with a name =
"myTreeViewControl"

Me.Controls.Remove(myTreeViewControl)

newTreeView.Name = "myTreeViewControl"
newTreeView.Location = New System.Drawing.Point(12, 12)
newTreeView.Name = "myTreeViewControl"
newTreeView.Size = New System.Drawing.Size(377, 389)
newTreeView.TabIndex = 0

newTreeView.SelectedNode = newTreeView.Nodes(0)
newTreeView.SelectedNode.Expand()

myTreeViewControl = newTreeView
myTreeViewControl.Enabled = True

Me.Controls.Add(myTreeViewControl)

End Sub

Private Sub btnAddNewChildNode_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnAddNewChildNode.Click

myTreeViewControl.Nodes(0).Nodes.Add(New TreeNode("New Child Node
04"
 
 
 

Assigning TreeView Class Instance to a TreeView Control

Post by Steve Gerr » Sat, 12 Apr 2008 11:40:07


Nicely done, and nicely tested. You may not have gotten it at first, but you
clearly get it now.