We're a community of 1077K IT Pros here for help, advice, solutions, professional growth and fun. Join us!
1,076,515 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Start New Discussion Reply to this Discussion

Accessing form controls from another thread

Hello,

How can I go about hiding a form from another thread.

I have two forms and a module, from the module I have started a new thread and at some point during this thread I want to hide the second form. How would I go about this as everything I have tried has not worked so far.

Thanks in advance,

Minko

5
Contributors
7
Replies
10 Hours
Discussion Span
4 Months Ago
Last Updated
8
Views
Question
Answered
Minko
Light Poster
26 posts since Jun 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

I have one suggestion (not necessarily a great one). Set a class variable in the main form (call it something like ShowForm). Set it to True initially. Have a timer on the main form and set the interval to 1000. In the timer Tick event do

Me.Visible = ShowForm

You can modify the value of ShowForm from another thread. The Tick event in the main form will do the actual show/hide. If you need the show/hide to be more reactive then shorten the Interval value.

Reverend Jim
Carpe per diem
Moderator
3,627 posts since Aug 2010
Reputation Points: 563
Solved Threads: 452
Skill Endorsements: 32

Ok, thanks for replying. I have already used this method, I was just wandering if there was a better way of doing this?.

Many thanks,

Minko

Minko
Light Poster
26 posts since Jun 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

I'm not sure I understand your situation correctly, but UI controls must be manipulated only on the thread that created them. Here is an example that flashes Form2. Note the pattern used with the InvokeRequired.

Public Class Form1
   Private WithEvents bgw As New System.ComponentModel.BackgroundWorker With {.WorkerSupportsCancellation = True}

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      bgw.RunWorkerAsync()
   End Sub

   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
      bgw.CancelAsync() ' cancel backgroundworker
   End Sub

   Private Sub ToggleForm2()
      If Me.InvokeRequired Then
         ' on other thread so call on UI thread
         Me.Invoke(New MethodInvoker(AddressOf ToggleForm2))
         Exit Sub ' on non UI thread
      End If

      Form2.Visible = Not Form2.Visible

   End Sub

   Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
      Do
         If bgw.CancellationPending Then
            e.Cancel = True
            Exit Do
         End If
         ToggleForm2()
         Threading.Thread.Sleep(1000)
      Loop
   End Sub

End Class
TnTinMN
Practically a Master Poster
640 posts since Jun 2012
Reputation Points: 418
Solved Threads: 148
Skill Endorsements: 13

@TnTinMN Thanks, for replying. However I have already tried this method and it did not work for me. The thread is running in a module so I can not use me.invoke so I tried to do form1.invoke but it errors saying the handle has not been created. Also just to note if I do form1.invokeRequired it returns false but still does not hide the form.

At the moment I think I will go ahead and use what Reverend Jim said. However if anybody else has a better solution then please do say.

Many thanks to both of you,

Minko

Minko
Light Poster
26 posts since Jun 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

one other thing to try, is when you call the routine in the module, pass the Form1.Handle as a parameter. You should be able to control it then.

tinstaafl
Nearly a Posting Virtuoso
1,336 posts since Jun 2010
Reputation Points: 360
Solved Threads: 235
Skill Endorsements: 14

If by "The thread is running in a module" you mean that the method being executed is in a Module, a similar technique can be used. Here is a slightly different version executing a method defined in a module.

Public Class Form1

   Private myParameterInstance As MyParameter
   Dim thrd As Threading.Thread

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      thrd = New Threading.Thread(AddressOf Something.threadMethod)
      myParameterInstance = New MyParameter(New MethodInvoker(AddressOf ToggleForm2))
      thrd.Start(myParameterInstance)
   End Sub

   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
      myParameterInstance.Cancel = True
   End Sub

   Private Sub ToggleForm2()
      If Me.InvokeRequired Then
         ' on other thread so call on UI thread
         Me.Invoke(New MethodInvoker(AddressOf ToggleForm2))
         Exit Sub ' on non UI thread
      End If
      Form2.Visible = Not Form2.Visible
   End Sub

   Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
      ' Clean up
      If myParameterInstance IsNot Nothing Then
         myParameterInstance.Cancel = True 'shut the thread down
         While thrd.IsAlive
            Threading.Thread.Sleep(500)
            Debug.WriteLine("waiting to end")
         End While
      End If
   End Sub
End Class

' Define a parameter class that contains the info to be passed to the threaded method
' You could just pass a MethodInvoker instance, but I like having a way to cancel a thread
' so I use a Class with a Cancel Property
Friend Class MyParameter

   Public mi As MethodInvoker 'use a simple MethodInvoker to execute a UI method
   Public Sub New(ByVal mi As MethodInvoker)
      Me.mi = mi
   End Sub

   Private _Cancel As Boolean
   Public Property Cancel() As Boolean
      Get
         Return _Cancel
      End Get
      Set(ByVal value As Boolean)
         _Cancel = value
      End Set
   End Property 'Cancel
End Class

Module Something
   Sub threadMethod(ByVal parameter As Object)
      ' the parameter must be passed as an Object
      ' convert it to an instance of MyParameter
      Dim param As MyParameter = CType(parameter, MyParameter)

      Do Until param.Cancel
         param.mi.Invoke()
         Threading.Thread.Sleep(2500)
      Loop
   End Sub
End Module
TnTinMN
Practically a Master Poster
640 posts since Jun 2012
Reputation Points: 418
Solved Threads: 148
Skill Endorsements: 13

Thank you to everybody for helping. I have managed to sort my problem out so I will mark this as solved. once again thanks to everyone who helped.

Kindest Regards,

Minko

Minko
Light Poster
26 posts since Jun 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0
Question Answered as of 4 Months Ago by TnTinMN, tinstaafl and Reverend Jim

This question has already been solved: Start a new discussion instead

Post: Markdown Syntax: Formatting Help
 
You
 
© 2013 DaniWeb® LLC
Page rendered in 0.0762 seconds using 2.68MB