Controls created on one thread cannot be parented to a control on a different thread.
-
Hello Guys, I am trying to mark locations on a map (x,y pixels are derived from a DB) This is the code that i am using
Private Sub DisplayOnSoftMap() SqlQuey = "Select * FROM SoftwareMap WHERE SoftwareMap.SMSID =myRndTrip.CurrentSwitch.SID & "'" tmpSoftMapCol = tmpSoftMapCol.GetAllSoftwareMap(SqlQuey) For Each tmpSoftMap In tmpSoftMapCol DrowLabel(tmpSoftMap.XMap, tmpSoftMap.YMap, tmpSoftMap.LablName) next Private Sub DrowLabel(ByVal X As Long, ByVal Y As Long, ByVal lblText As String) Dim LIndex, Lcount As Integer Try If Lbl Is Nothing Then ReDim Preserve Lbl(0) Lcount = 1 LIndex = 0 Else Lcount = Lbl.Length ReDim Preserve Lbl(Lcount) LIndex = Lcount End If Lbl(LIndex) = New LinkLabel Control.CheckForIllegalCrossThreadCalls = False Lbl(LIndex).Location = New System.Drawing.Point(X, Y) Lbl(LIndex).Text = lblText Lbl(LIndex).Visible = True Lbl(LIndex).AutoSize = True Control.CheckForIllegalCrossThreadCalls = False Me.Controls.Add(Lbl(LIndex)) AddHandler Lbl(LIndex).Click, AddressOf Label_Click Catch ex As Exception Throw ex End Try End Sub
And this is the Error that Occurs System.ArgumentException was caught Message="Controls created on one thread cannot be parented to a control on a different thread." Source="System.Windows.Forms" StackTrace: at System.Windows.Forms.Control.ControlCollection.Add(Control value) at System.Windows.Forms.Form.ControlCollection.Add(Control value) at RoundTrip.frmRoundTrip.DrowLabel(Int64 X, Int64 Y, String lblText) -- The purpose of this code is to mark locations on a map, I would be glad: if you help me finding the solution or any other solution which fits my needsRegards Ramy
-
Hello Guys, I am trying to mark locations on a map (x,y pixels are derived from a DB) This is the code that i am using
Private Sub DisplayOnSoftMap() SqlQuey = "Select * FROM SoftwareMap WHERE SoftwareMap.SMSID =myRndTrip.CurrentSwitch.SID & "'" tmpSoftMapCol = tmpSoftMapCol.GetAllSoftwareMap(SqlQuey) For Each tmpSoftMap In tmpSoftMapCol DrowLabel(tmpSoftMap.XMap, tmpSoftMap.YMap, tmpSoftMap.LablName) next Private Sub DrowLabel(ByVal X As Long, ByVal Y As Long, ByVal lblText As String) Dim LIndex, Lcount As Integer Try If Lbl Is Nothing Then ReDim Preserve Lbl(0) Lcount = 1 LIndex = 0 Else Lcount = Lbl.Length ReDim Preserve Lbl(Lcount) LIndex = Lcount End If Lbl(LIndex) = New LinkLabel Control.CheckForIllegalCrossThreadCalls = False Lbl(LIndex).Location = New System.Drawing.Point(X, Y) Lbl(LIndex).Text = lblText Lbl(LIndex).Visible = True Lbl(LIndex).AutoSize = True Control.CheckForIllegalCrossThreadCalls = False Me.Controls.Add(Lbl(LIndex)) AddHandler Lbl(LIndex).Click, AddressOf Label_Click Catch ex As Exception Throw ex End Try End Sub
And this is the Error that Occurs System.ArgumentException was caught Message="Controls created on one thread cannot be parented to a control on a different thread." Source="System.Windows.Forms" StackTrace: at System.Windows.Forms.Control.ControlCollection.Add(Control value) at System.Windows.Forms.Form.ControlCollection.Add(Control value) at RoundTrip.frmRoundTrip.DrowLabel(Int64 X, Int64 Y, String lblText) -- The purpose of this code is to mark locations on a map, I would be glad: if you help me finding the solution or any other solution which fits my needsRegards Ramy
Setting 'CheckForIllegalCrossThreadCalls' to false won't help you in this case. I tried it myself and I get the same error you do. You could do that way if you were changing the text of a control or something like that, but I don't think you should use that method in any circumstances. I don't know that for sure but I would guess not using that method is the recommended way to go. Here is a procedure you can call to safely add a control to the collection of another from any thread.
Delegate Sub AddControlDelegate(ByVal parent As Control, ByVal child As Control) 'Safely adds any control to the collection of another 'parent: The control that is the container 'child: The control to add Private Sub AddControl(ByVal parent As Control, ByVal child As Control) If parent.InvokeRequired Then parent.Invoke(New AddControlDelegate(AddressOf AddControl), New Object() {parent, child}) Else parent.Controls.Add(child) End If End Sub
Now when you want to add your label you just use this procedure to safely do it from any thread you wish.
AddControl(me,lbl(Lindex))
For a more in depth tutorial on updating the UI from secondary threads you should read this article http://msdn.microsoft.com/msdnmag/issues/04/05/BasicInstincts/default.aspx[^] and/or search the web. For the moment though you just need to know my procedure works :) -- modified at 4:38 Saturday 17th February, 2007
-
Setting 'CheckForIllegalCrossThreadCalls' to false won't help you in this case. I tried it myself and I get the same error you do. You could do that way if you were changing the text of a control or something like that, but I don't think you should use that method in any circumstances. I don't know that for sure but I would guess not using that method is the recommended way to go. Here is a procedure you can call to safely add a control to the collection of another from any thread.
Delegate Sub AddControlDelegate(ByVal parent As Control, ByVal child As Control) 'Safely adds any control to the collection of another 'parent: The control that is the container 'child: The control to add Private Sub AddControl(ByVal parent As Control, ByVal child As Control) If parent.InvokeRequired Then parent.Invoke(New AddControlDelegate(AddressOf AddControl), New Object() {parent, child}) Else parent.Controls.Add(child) End If End Sub
Now when you want to add your label you just use this procedure to safely do it from any thread you wish.
AddControl(me,lbl(Lindex))
For a more in depth tutorial on updating the UI from secondary threads you should read this article http://msdn.microsoft.com/msdnmag/issues/04/05/BasicInstincts/default.aspx[^] and/or search the web. For the moment though you just need to know my procedure works :) -- modified at 4:38 Saturday 17th February, 2007
Thx/...
Regards Ramy