How to interact with Listbox from Form2 throught thread from Form1 - vb.net

I tried to add items to Listbox in Form2 but noting can't be added, when I put listbox in same form where is thread it works good...Could someone help to make it work with Form2? Here is code:
Public Class Form1
Dim testthread As Threading.Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Control.CheckForIllegalCrossThreadCalls = False
testthread = New Threading.Thread(AddressOf testira)
testthread.Start()
End Sub
Sub testira()
Form2.ListBox1.Items.Add(TextBox1.Text)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Form2.Show()
End Sub
End Class

Here's an example...
Public Class Form1
Private f2 As New Form2
Private Delegate Sub AddItemDelegate(ByVal item As String)
Private Delegate Function GetTextboxTextDelegate(ByVal TB As TextBox) As String
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim testthread As New Threading.Thread(AddressOf testira)
testthread.Start()
End Sub
Sub testira()
Dim item As String = GetTextboxText(TextBox1)
AddItem(item)
End Sub
Private Function GetTextboxText(ByVal TB As TextBox) As String
If TB.InvokeRequired Then
Return TB.Invoke(New GetTextboxTextDelegate(AddressOf GetTextboxText), New Object() {TB})
Else
Return TB.Text
End If
End Function
Private Sub AddItem(ByVal item As String)
If Me.InvokeRequired Then
Me.Invoke(New AddItemDelegate(AddressOf AddItem), New Object() {item})
Else
If IsNothing(f2) OrElse f2.IsDisposed Then
f2 = New Form2
End If
f2.ListBox1.Items.Add(item)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If IsNothing(f2) OrElse f2.IsDisposed Then
f2 = New Form2
End If
f2.Show()
End Sub
End Class

Related

Error: Form1 is a type of windowsApplication cannot be used as an expression

How to solve error when passing and returning some data across the form in visual basic.
Error: Form1 is a type of windowsApplication cannot be used as an
expression
showin error on "Form 1" (Public Class Form1)
FORM 1 CODE
Public Class Form1
Dim eid As String = ""
Public Sub New(ByVal empid As String)
InitializeComponent()
eid = empid
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Declare a variable of string type
Dim pass As String = TextBox1.Text
Dim frm As New Form2(pass)
frm.ShowDialog()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Label2.Text = eid.ToString()
End Sub
End Class
FORM 2 CODE
Public Class Form2
Dim eid As String = ""
Public Sub New(ByVal empid As String)
InitializeComponent()
eid = empid
End Sub
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Label1.Text = eid.ToString()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim value As String = TextBox2.Text
Dim fr As New Form1(value)
fr.ShowDialog()
End Sub
End Class
To solve your error message add this to your Form1 Class
Public Sub New()
InitializeComponent()
End Sub
If you are trying to pass values between forms, you might find this link useful...
http://grantwinney.com/passing-data-between-two-forms-in-winforms/
Public Class Form1
Dim eid As String = ""
Public Sub New(ByVal empid As String)
InitializeComponent()
eid = empid
End Sub
Public Sub New()
InitializeComponent()
End Sub
startup form isn't being called with any parameters
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Declare a variable of string type
Dim pass As String = TextBox1.Text
Dim frm As New Form2(pass)
frm.ShowDialog()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Label2.Text = eid.ToString()
End Sub
End Class
It happens when you change the project type from class library to windows forms in visual studio.
Head to Application.Designer.vb in your project and there you'll find something like this:
Namespace My
'NOTE: This file is auto-generated; do not modify it directly. To make changes,
' or if you encounter build errors in this file, go to the Project Designer
' (go to Project Properties or double-click the My Project node in
' Solution Explorer), and make changes on the Application tab.
'
Partial Friend Class MyApplication
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Public Sub New()
MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
Me.IsSingleInstance = false
Me.EnableVisualStyles = true
Me.SaveMySettingsOnExit = true
Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses
End Sub
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = Global.AeonLabs.Layouts.Main.mainAppLayoutForm
End Sub
End Class
End Namespace
in the sub OnCreateMainForm() where it has OnCreateMainForm change it to something like this
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = New Global.AeonLabs.Layouts.Main.mainAppLayoutForm
End Sub
and you'll be good to go!!

combobox multiple thread error

I have a problem with my code. I keep getting Multiple thread Error with backgroundworker, because of the combobox item display. Please look at my code below its a very simple code which I am planning to use on big scale, all I want it to do is "If item "1" selected show item "1" in label1. I can only assume that problem exists because Combobox runs in different thread....
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.runworkerasync()
BackgroundWorker1.WorkerReportsProgress = True
Me.Cursor = Cursors.WaitCursor 'Cursor changes to wait
End Sub
Public Structure controlwithtext
Public controlname As Control
Public text As String
Public Sub New(ByVal ctrl As Control, ByVal text As String)
Me.controlname = ctrl
Me.text = text
End Sub
End Structure
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
If comboBox1.SelectedItem = "1" then
BackgroundWorker1.ReportProgress(5, New controlwithtext(Label1, ComboBox1.SelectedItem))
End If
End Sub
Private Sub SetBackgroundWorker_ProgressChanged(ByVal sender As Object,
ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
If TypeOf e.UserState Is controlwithtext Then
Dim cwt As controlwithtext = CType(e.UserState, controlwithtext)
cwt.controlname.Text = cwt.text
End If
End Sub
Here's an example of how to read from and write to controls from the BackgroundWorker thread:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While True
System.Threading.Thread.Sleep(250)
Dim selection As String = Me.Invoke(Function()
If Not IsNothing(ComboBox1.SelectedItem) Then
Return ComboBox1.SelectedItem.ToString
Else
Return String.Empty
End If
End Function).ToString
If selection = "1" Then
Me.Invoke(Sub()
Label1.Text = ComboBox1.SelectedItem.ToString
End Sub)
Else
Me.Invoke(Sub()
Label1.Text = "something else"
End Sub)
End If
End While
End Sub

Multi Threading For getting links from Webbrowser1.Document

The problem is that multi threading is not working properly for getting links from webbrowser1.document.links. How can I solve this problem?
Public Class Form1
Dim thread1 As System.Threading.Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
thread1 = New System.Threading.Thread(AddressOf GetLinks)
thread1.Start()
End Sub
Private Sub GetLinks()
For i As Integer = 0 To WebBrowser1.Document.Links.Count - 1
If TextBox1.Text.Length > 0 Then
TextBox1.Text += Environment.NewLine & WebBrowser1.Document.Links(i).ToString
Else
TextBox1.Text = WebBrowser1.Document.Links(i).ToString
End If
Next
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate("www.google.com")
Me.CheckForIllegalCrossThreadCalls = False
End Sub
End Class
You can't make a call to one of the controls on the form (in this case, TextBox1 and WebBrowser1) from another thread other than the main thread of the form. You need to use a delegate.
This will do the trick:
Private _iLinks As Integer
Dim thread1 As System.Threading.Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
CheckForIllegalCrossThreadCalls = False
_iLinks = WebBrowser1.Document.Links.Count
thread1 = New System.Threading.Thread(AddressOf GetLinks)
thread1.Start()
End Sub
Private Sub GetLinks()
For i As Integer = 0 To _iLinks - 1
UpdateTextBoxDelegate(i)
Next
End Sub
Private Sub UpdateTextBox(ByVal iLink As Integer)
If TextBox1.Text.Length > 0 Then
TextBox1.Text += Environment.NewLine & WebBrowser1.Document.Links(iLink).ToString
Else
TextBox1.Text += WebBrowser1.Document.Links(iLink).InnerText.ToString()
End If
End Sub
Private Delegate Sub UpdateTextBoxCallback(ByVal iLink As Integer)
Private Sub UpdateTextBoxDelegate(ByVal iLink As Integer)
Try
If Me.InvokeRequired Then
Dim cb As New UpdateTextBoxCallback(AddressOf UpdateTextBox)
Me.Invoke(cb, New Object() {iLink})
Else
UpdateTextBox(iLink)
End If
Catch ex As Exception
MessageBox.Show("There was an error " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate("http://stackoverflow.com/")
End Sub

update form on asynchronous control event

A few weeks ago I wrote a wrapper for the ServiceController control to enhance and streamline the base ServiceController. One of the changes I made was to add a monitoring component using the System.Threading.Timer object. On any change of status, an event is raised to the parent class. The actual monitoring works fine, but when the event is handled in the main form, my program abruptly ends - no exceptions, no warning, it just quits. Here's a skeleton version of the control:
Public Class EnhancedServiceController
Inherits ServiceController
Public Event Stopped(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event Started(ByVal sender As Object, ByVal e As System.EventArgs)
Private _LastStatus As System.ServiceProcess.ServiceControllerStatus
Private serviceCheckTimer as System.Threading.Timer
Private serviceCheckTimerDelegate as System.Threading.TimerCallback
...
Private Sub StartMonitor()
MyBase.Refresh()
_LastStatus = MyBase.Status
serviceCheckTimerDelegate = New System.Threading.TimerCallback(AddressOf CheckStatus)
serviceCheckTimer = New System.Threading.Timer(serviceCheckTimerDelegate, Nothing, 0, 60*1000)
End Sub
Private Sub CheckStatus()
MyBase.Refresh()
Dim s As Integer = MyBase.Status
Select Case s
Case ServiceControllerStatus.Stopped
If Not s = _LastStatus Then
RaiseEvent Stopped(Me, New System.EventArgs)
End If
Case ServiceControllerStatus.Running
If Not s = _LastStatus Then
RaiseEvent Started(Me, New System.EventArgs)
End If
End Select
_LastStatus = s
End Sub
End Class
And the form:
Public Class Form1
Private Sub ServiceStarted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Started
Me.TextBox1.Text = "STARTED"
End Sub
Private Sub ServiceStopped(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Stopped
Me.TextBox1.Text = "STOPPED"
End Sub
End Class
If I had to guess, I'd say that there's some sort of thread problem, but I'm not sure how to handle that in the form. Any ideas?
IF it is a threading issue then you are probably trying to update the UI from a non-UI thread.
So something like this should solve that...
Private Delegate Sub UpdateTextBoxDelegate(byval tText as String)
Private Sub UpdateTextBox(byval tText As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateTextBoxDelegate(AddressOf UpdateTextBox), tText)
Exit Sub
End If
TextBox1.Text = tText
End Sub
Private Sub ServiceStarted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Started
UpdateTextBox ("STARTED")
End Sub
Private Sub ServiceStopped(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Stopped
UpdateTextBox("STOPPED")
End Sub

Open the same form more than once

Is it possible to open a form more than once?
button1
form2.show
Press button1
form2 opens up
press button1 again
another form2 opens up next to the old form2
If possible, can a button on Form1 kill all Form2 windows open?
Of course it's possible. Just dim two instances of the same form.
Public Class Form1
Private m_WindowList As New List(Of Form2)
Private Sub OpenWindowButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenWindowButton.Click
OpenWindow()
End Sub
Private Sub CloseWindowsButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseWindowsButton.Click
CloseWindows()
End Sub
Private Sub OpenWindowsButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenWindowsButton.Click
Dim WindowCount As Int32
If Int32.TryParse(WindowCountTextBox.Text, WindowCount) Then
OpenWindows(WindowCount)
End If
End Sub
Private Sub OpenWindow()
Dim NewWindow As New Form2
m_WindowList.Add(NewWindow)
NewWindow.Show()
End Sub
Private Sub OpenWindows(ByVal Count As Int32)
For i = 1 To Count
OpenWindow()
Next
End Sub
Private Sub CloseWindows()
For Each Window In m_WindowList
Window.Close()
Window.Dispose()
Next
m_WindowList.Clear()
End Sub
End Class
Dim MyNewForm2 = New Form2
MyNewForm2.Show