So, I need to do an program for a client and he wants a search bar in it. So I made it and everything worked perfectly but I put it in my main form. Now, I want to put it in a class but when I initialize the program, it gives me the following error
An error occurred while creating the form. For more information,
see Exception.InnerException. The error is: The form is self-reference during
construction from a default instance, which led to infinite recursion. In the
constructor of the form, refer to the form using 'Me'.
I tried to put Me.Rbtn_X... but it doesn't recognize it.
Initialization
' Main form
Public Sub New()
InitializeComponent()
Initialize_search()
End Sub
Initialize_search()
' Main form
' search is initialize like this :
' Dim search as New Research
Private Sub Initialize_search()
search.generate_autocomplete()
End Sub
generate_autocomplete()
' Research class
Sub generate_autocomplete()
' Main_form = Main form
Dim field = ""
' This is the place where the program fail
If Main_form.RbtnR_avancee_contact.Checked Then
field = "personneressource"
Else
field = "beneficiaire"
End if
' ....
End Sub
Is there something I didn't understand or It's not possible to do it that way?
Edit: added Form_shown event
Public Sub New()
InitializeComponent()
' Initialize_search()
End Sub
Private Sub Form_personne_Shown(sender As Object, e As EventArgs) Handles Me.Shown
MessageBox.Show("You are in the Form.Shown event.")
End Sub
The form is not created (fully) until New completes. By adding your Initialize_search to it, it eventually leads to the statement `Main_form.RbtnR_avancee_contact.Checked'. This is wrong on two counts:
1) the form doesnt exist yet, so you cant refer to it. (this is what the error meant with 'form is self-reference during construction')
2) the ref should be Me.RbtnR (which is what it meant by 'refer to the form using 'Me'')
Move your Initialize_search to the Form_shown event. Your code should look like this (including Lar's suggestion)
' Main form
Public Sub New()
' REQUIRED
InitializeComponent()
End Sub
If there is really something that needs to be setup for this, add it to the form_shown event:
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Shown
' NOTE: even .NET refers to ME not MainForm etc
InitializePanel
InitializeSeach
End Sub
Then:
Private Sub Initialize_search()
search.generate_autocomplete(Me.RbtnR_avancee_contact.Checked)
End Sub
Then:
Sub generate_autocomplete(AdvContact as Boolean)
Dim field AS STRING = ""
If AdvContact Then
field = "personneressource"
Else
field = "beneficiaire"
End if
' ....
End Sub
Your search class doesn't have a reference to the instance of the form's controls.
Try passing the value instead:
Sub generate_autocomplete(advancedChecked As Boolean)
Dim field As String = ""
If advancedChecked Then
field = "personneressource"
Else
field = "beneficiaire"
End if
End Sub
Then when you call it:
search.generate_autocomplete(Me.RbtnR_avancee_contact.Checked)
Even if did work like you want it to, according to your code, it would always result in field containing the same value (whichever was set in designer).
Instead, try putting this code inside RbtnR_avancee_contact.Checked event. Or even TextChanged for the autocomplete box (and initialize it for the first time user enters anything), it would examine the checked state and populate autocomplete items.
With this approach, if your user never uses the search box, you don't need to initialize it.
Related
I have a form called "partmanager". On it is a button to show another form "parteditor" to allow editing details of a part. Clicking that button will show the form and pass in a variable to the parteditors "new" routine.
My problem is that when the calling form (partmanager) starts, it immediately calls new routine in the parteditor form before it (partmanager) is even initialized so the parteditor form does not get the string that is supposed to be passed in. Later, when the calling form is visible and I click the button to show the parteditor form, new has already been prematurely called and so is not called again and the form does not get the string passed in.
I hope this makes sense!
I can implement a property in the parteditor form and pass in my variable that way prior to showing the form and that will work, thereby not even requiring a "new" routine in the parteditor forms code.
So my question is, is implementing the property the proper way to pass this variable to the form being called, or am I not properly coding my forms? (I also have an intermediary module called "commands" where I have been defining command procedures, in this case just showing a form.)
any pointers would be appreciated, thanks!
here is the code for the button in the calling form:
Private Sub EditButton_Click(sender As Object, e As EventArgs) Handles EditButton.Click
Commands.EditPart(_PartNumber) 'call the editpart command
Me.Close()
Me.Dispose()
End Sub
here is the code for the form being called:
Public Class PartEditForm
Private _partNumber As String = String.Empty
Public Sub New(partNumber As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_partNumber = partNumber
End Sub
Private Sub PartEditForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Label1.Text = _partNumber
End Sub
End Class
and here is the code in my "commands" module for loading/showing the form:
Public PartEditForm As New PartEditForm(_partNumber)
Public Sub EditPart(partnumber As String)
If PartEditForm.IsDisposed Then
PartEditForm = New PartEditForm(partnumber)
End If
PartEditForm.Show()
End Sub
you can save the routine in a dim variable and get this on the other form and close the first form or hide but you need get in new var and contine where stop before.
I have created 2 forms.
The first one is the button that you want to back up.
In the second there are paths that can be modified.
How to make a reference that after pressing the "backup" button will get a path of 2 forms.
The path is saved when I closed form2
I know how to do it in one form but unfortunately I can not refer to another form.
Source of Form 2:
Private Sub Browser_from1_Click(sender As Object, e As EventArgs) Handles Browser_from1.Click
Dim FolderBrowserDialog1 As New FolderBrowserDialog
FolderBrowserDialog1.ShowDialog()
TextBox1from.Text = FolderBrowserDialog1.SelectedPath
If Browser_from1.Text <> "" And TextBox1from.Text <> "" Then
Backup.StartCopy.Enabled = True
End If
End Sub
Private Sub Browser_to1_Click(sender As Object, e As EventArgs) Handles Browser_to1.Click
Dim FolderBrowserDialog1 As New FolderBrowserDialog
FolderBrowserDialog1.ShowDialog()
TextBox2to.Text = FolderBrowserDialog1.SelectedPath
If Browser_to1.Text <> "" And TextBox2to.Text <> "" Then
Backup.StartCopy.Enabled = True
End If
End Sub
Private Sub TextBox1from_TextChanged(sender As Object, e As EventArgs) Handles TextBox1from.TextChanged
End Sub
Private Sub save_settings_Click(sender As Object, e As EventArgs) Handles save_settings.Click
My.Settings.pathmem = TextBox2to.Text
My.Settings.pathmem1 = TextBox1from.Text
My.Settings.Save()
End Sub
Private Sub setting_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1from.Text = My.Settings.pathmem1
TextBox2to.Text = My.Settings.pathmem
End Sub
End Class
You dont want to create a reference to a form - that would (or could) create a whole new form. You want to hold onto the form reference.
This is done by passing a reference to the forms, but the talk of one form fiddling with the controls on another form is a bad idea because it breaks encapsulation. But forms are classes (it says so at the top of each one), so you can add Properties and Methods (Sub and/or Functions) to facilitate passing information back and forth.
Method One - Passing a Form Reference
The simplest way is to pass whatever the other form needs in the constructor:
' form 1 / "main" form / form to return to
Dim frm As New Form6(Me)
frm.Show()
Me.Hide()
In order for this to work, you need to modify the constructor (Sub New) on the destination form:
Private frmReturnTo As Form
Public Sub New(f As Form)
' This call is required by the designer.
InitializeComponent()
frmReturnTo = f
End Sub
It is best not to create your own constructor until you are familiar with them. Use the drop downs at the top of the code window: from the left pick the form name; from the right, select New. The designer adds required code to them which must not be changed.
Do not add any code before the InitializeComponent() call at least until you are familiar with the life cycle of a form. The form and its controls do not exist until that runs.
To return to the "main" form:
If frmReturnTo IsNot Nothing Then
frmReturnTo.Show()
End If
You may want to remove some of the title bar buttons or add code to the form Closing event to handle when the user closes via the system menu or buttons.
Using the constructor is ideal for cases where there is some bit of data which the form must have in order to do its job.
Method Two - Passing Data
Thats all well and good, but what about passing data to another form? You can use the constructor for that too. In order to pass say, a string, integer and a Point:
' destination / second form:
Public Sub New(a As String, b As Int32, c As Point)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Label1.Text = a
Label2.Text = b.ToString
Label3.Text = c.ToString
End Sub
Call it like this:
' method two: pass data you want to share in the ctor
Dim frm As New frmData("hello", 6, New Point(150, 550))
frm.Show()
Result:
Method Three: Properties
Thats fine, but if there is a lots of data that way can get cumbersome. Plus, you may want to update some of the data from the calling/main form. For this you can create Properties on the form to handle the data:
Public Property Label1Text As String
Get
Return Me.Label1.Text
End Get
Set(value As String)
Me.Label1.Text = value
End Set
End Property
Rather than a private variable to act as the backing field, one of the controls is used. The name leaves a bit to be desired as it exposes implementation details. So, use names which describe what the data represents rather than where it displays.
Public Property SpecialValue As Integer
Get
Return Integer.Parse(Me.Label2.Text)
End Get
Set(value As Integer)
Me.Label2.Text = value.ToString
End Set
End Property
Public Property SomePoint As Point
Get
Dim data = Me.Label3.Text.Split(","c)
Return New Point(Convert.ToInt32(data(0)),
Convert.ToInt32(data(1))
)
End Get
Set(value As Point)
Me.Label3.Text = value.X.ToString & "," & value.Y.ToString
End Set
End Property
A point was used just to show that other data types can be used. Setting those values from the calling/original/source form:
Using frm As New Form6
frm.Label1Text = "Ziggy"
frm.SpecialValue = 42
frm.SomePoint = New Point(111, 222)
frm.ShowDialog()
' do stuff here with any changes
Dim theint = frm.SpecialValue
End Using ' dispose of dialog
The destination controls would well have been TextBoxes for the user to edit. The Property "wrappers" allow you to fetch those values back, so in this case, a Dialog was used.
Method Four: Methods
You can also use methods as a way to pass data to the second/helper form. Here a List(of T) collection will be passed. In the child/display form a method is added to receive the data which it then displays. The task represented is proofing or viewing a filtered list:
Public Sub UpdateDisplay(lst As List(Of SimpleItem), filter As String)
DataGridView1.DataSource = lst
Label1.Text = String.Format("{0} Total {1} Items", lst.Count, filter)
End Sub
In the main/calling form:
' form level variable
Private frmDV As frmDataView
elsewhere...perhaps in a Click event:
' myList is a simple list of items
' Users pick which color to filter on via a combo box
Dim filter As String
If cboListFilter.SelectedItem IsNot Nothing Then
'Dim frmDV As New frmDataView
If frmDV Is Nothing OrElse frmDV.IsDisposed Then
frmDV = New frmDataView
End If
filter = cboListFilter.SelectedItem.ToString()
' apply the filter
Dim tmpList = myList.Where(Function(w) w.Color = filter).ToList()
frmDV.UpdateDisplay(tmpList, filter)
frmDV.Show()
Else
Return
End If
Result:
With DataBased apps a modified version of this can allow for the case where you display DataGridView data in detail form on another form. You need not have the second form rung SQL to add or update the record, and then the main form running another query to "refresh" the display. If the DataSource is a DataTable backed up by a fully configured DataAdapter, pass the DataTable and have the child form add, change or delete using that. The data will automagically be in the DataTable and DataGridView`.
There are other ways to do this, but they generally all boil down to passing something from A to B. Which way is "best" depends on what the app does, the use-case and the nature of the data. There is no one right way or best way.
For instance, Properties and in many cases Functions allow the B Form to close the feedback loop. With DB items, a DataChanged property might tell the calling form that data was added or changed so that form knows to use the DataAdapter to update the db.
'SECOND FORM
Public class secondForm (blah blah)
Public overloads property owner as myMainForm
'Must be only the form you prepared for that
Private sub secondForm_load(blah blah) handles blah blah
Texbox1.text=Owner.customcontrol.text
End sub
End class
'MAIN FORM
public class myMainForm(blah blah)
Private sub button1_click(blah blah) handles blah blah
Dim NewSecondForm as secondForm = New secondForm
NewSecondForm.owner(me)
NewSecondForm.show(me)
NewSecondForm.dispose()
' so you can have bidirectional communication between the two forms and access all the controls and properties from each other
End sub
End Class
On every DataGridView1_SelectionChanged event I need to run a Private Sub OnSelectionChanged() of the form that is loaded into Panel1 (see the image http://tinypic.com/r/2nu2wx/8).
Every form that can be loaded into Panel1 has the same Private Sub OnSelectionChanged() that initiates all the necessary calculations. For instance, I can load a form that calculates temperatures or I can load a form that calculates voltages. If different element is selected in the main form’s DataGridView1, either temperatures or voltages should be recalculated.
The problem is - there are many forms that can be loaded into Panel1, and I’m struggling to raise an event that would fire only once and would run the necessary Sub only in the loaded form.
Currently I’m using Shared Event:
'Main form (Form1).
Shared Event event_UpdateLoadedForm(ByVal frm_name As String)
'This is how I load forms into a panel (in this case frm_SCT).
Private Sub mnu_SCT_Click(sender As Object, e As EventArgs) Handles mnu_SCT.Click
frm_SCT.TopLevel = False
frm_SCT.Dock = DockStyle.Fill
Panel1.Controls.Add(frm_SCT)
frm_SCT.Show()
Var._loadedForm = frm_SCT.Name
RaiseEvent event_UpdateLoadedForm(Var._loadedForm)
End Sub
‘Form that is loaded into panel (Form2 or Form3 or Form4...).
Private WithEvents myEvent As New Form1
Private Sub OnEvent(ByVal frm_name As String) Handles myEvent.event_UpdateLoadedForm
‘Avoid executing code for the form that is not loaded.
If frm_name <> Me.Name Then Exit Sub
End Sub
This approach is working but I’m sure it can be done way better (I'd be thankful for any suggestions). I have tried to raise an event in the main form like this:
Public Event MyEvent As EventHandler
Protected Overridable Sub OnChange(e As EventArgs)
RaiseEvent MyEvent(Me, e)
End Sub
Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _
Handles DataGridView1.SelectionChanged
OnChange(EventArgs.Empty)
End Sub
but I don't know to subscribe to it in the loaded form.
Thank you.
Taking into account Hans Passant’s comments as well as code he posted in related thread I achieved what I wanted (see the code below).
Public Interface IOnEvent
Sub OnSelectionChange()
End Interface
Public Class Form1
' ???
Private myInterface As IOnEvent = Nothing
' Create and load form.
Private Sub DisplayForm(frm_Name As String)
' Exit if the form is already displayed.
If Panel1.Controls.Count > 0 AndAlso _
Panel1.Controls(0).GetType().Name = frm_Name Then Exit Sub
' Dispose previous form.
Do While Panel1.Controls.Count > 0
Panel1.Controls(0).Dispose()
Loop
' Create form by its full name.
Dim T As Type = Type.GetType("Namespace." & frm_Name)
Dim frm As Form = CType(Activator.CreateInstance(T), Form)
' Load form into the panel.
frm.TopLevel = False
frm.Visible = True
frm.Dock = DockStyle.Fill
Panel1.Controls.Add(frm)
' ???
myInterface = DirectCast(frm, IOnEvent)
End Sub
Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _
Handles DataGridView1.SelectionChanged
' Avoid error if the panel is empty.
If myInterface Is Nothing Then Return
' Run subroutine in the loaded form.
myInterface.OnSelectionChange()
End Sub
End Class
One last thing – it would be great if someone could take a quick look at the code (it works) and confirm that it is ok, especially the lines marked with “???” (I don’t understand them yet).
i have my form class, and a second module with some special functions,
when i click a button on my form i run a public function from the second module(which run later other public functions from the second module) in a separated thread, i set SetApartmentState(ApartmentState.STA), and i tried using deletage sub and CheckForIllegalCrossThreadCalls = False, but the problem stays the same, my thread functions (which are on the second module) can't access my form controls, but when i move the functions to the form class everything work again, what do you suggest to solve this issue?
Public Class Form1
Dim T0 As Thread
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
T0 = New Thread(AddressOf sub1)
T0.SetApartmentState(ApartmentState.STA)
T0.start()
End Sub
End Class
Module Module1
Public Sub Sub1()
msgbox(form1.textbox1.text) 'even if the textbox contains content it returns ""
Function2()
End Sub
Public Function Function1()
'SomeInstructions
msgbox(form1.textbox1.text) 'same problem here
End Function
End module
PS: it dosn't give any error or stop the code while debugging, and i tried to put the sub1 on the form class and the other functions in the module, but then, only he sub1 can access the controls, i tried delegate but i don't know if i have done it right, can anyone make any suggestions please
There are two issues at play here.
One of them is due to the way default forms work in VB.NET. See, in C# you need a concrete instance of type Form1 in order to access its non-static members, whereas in VB.NET Form1 looks like an instance of the form allowing you to write things like Form1.TextBox1.Text. This works fine while you're accessing members of Form1 from the UI thread, but when you try to get it from a background thread, a new instance of Form1 is created, and Form1.TextBox1 seen by that thread actually points to a completely different instance of TextBox.
Another way saying this is that default form instances in VB.NET are thread static.
A way to get around this is to keep a concrete reference to Form1 so that you can pass it around.
When you go
Dim myForm As New Form1
... or
Dim myForm As Form1 = Me
... the 'myForm' variable pointing to that specific Form1 instance can then be passed between threads like any other reference and will not change its meaning.
This, however, brings us to issue #2:
You should not be accessing a UI control (which means any type derived from Control, and that includes Form , from a thread other than the thread that it was created on.
If you absolutely have to, you have to marshal the calls accessing the Control to the thread that it was created on, for example by using Invoke/BeginInvoke (there are other ways too).
Here's a modification of your code to achieve what you want, plus a more complex example which demonstrates multiple thread "switches": gathering interesting state on the UI thread, performing work with it on the background thread, then displaying results on the UI thread.
Imports System.Threading
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' We don't need this anymore.
' We'll do things right and access
' the UI on the UI thread only.
' CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Note that we're passing a reference
' to THIS instance of Form1 to Sub1 and Sub2.
Dim form As Form1 = Me
' Let's spin up some threads.
Dim T0 As New Thread(Sub() Module1.Sub1(form))
T0.Start()
Dim T1 As New Thread(Sub() Module1.Sub2(form))
T1.Start()
End Sub
End Class
Module Module1
' Note that this sub now accepts
' a reference to an instance of Form1.
Public Sub Sub1(form As Form1)
' This is what we want to do:
Dim action As New Action(Sub() MsgBox(form.TextBox1.Text))
' See if we're on the right thread.
If form.InvokeRequired Then
' Invoke on the thread which created this Form1 instance.
form.Invoke(action)
Else
' Invoke on the current thread.
action.Invoke()
End If
End Sub
' This is a more complex example.
Public Sub Sub2(form As Form1)
' This function will get the text from TextBox1 when invoked.
' It still needs to be invoked on the UI thread though.
Dim getText As New Func(Of String)(Function() form.TextBox1.Text)
Dim text As String
If form.InvokeRequired Then
text = CStr(form.Invoke(getText))
Else
text = getText() ' Shorthand syntax.
End If
' Now that we have the text, let's do some
' intensive work with it while we're on
' the background thread.
For i = 0 To 5
text &= i
Thread.Sleep(100)
Next
' Now we want to show the message box - again, on the UI thread.
Dim showMessageBox As New Action(Sub() MsgBox(text))
If form.InvokeRequired Then
form.Invoke(showMessageBox)
Else
showMessageBox()
End If
End Sub
End Module
I am trying to have a variable input come from a combobox. i had thought it would be a simpler task but i am stuck on this and would be grateful for some help.
i am working with pre-packaged code that connects to an API, connects to a server and does stuff. I am customizing it to do a few additional calculations, all of which now work fine, but the variables i use to perform those calcs, inside of one of the sub-routines, are hard coded, and i want to be able to read them in instead using a combobox. i had done this many times using VB6 and VBA, but i am new to vb.net (2010) and even though i have the combobox on my form, every reference to the selected number in the combobox ends up with an empty result
in a simpler application, like the one below, i am able to get the data from the combo box:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim divisor As Integer
Dim res1 As Integer
If Int32.TryParse(ComboBox1.Text, divisor) Then
MsgBox(ComboBox1.Text)
Else
MsgBox("error" & ComboBox1.Text)
End If
res1 = divisor - 9
MsgBox(res1)
End Sub
End Class
Unfortunately the code i am working with is not cooperating with the code above. without posting all the code, here is the basic structure, maybe this will help you help me figure out where to write the code above so it will grab the value in the combobox where the 'divisor' in the sub13 (see below) will be the number from the combobox instead of it being hard coded
and every reference you see below to the combobox was 'auto-generated'. that is, once i placed the combobox on the form all of that code appeared.
Imports X.API
Public Class frmMain
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Protected Sub Dispose(ByVal disposing As Boolean)
End Sub
Private components As System.ComponentModel.IContainer
Friend WithEvents Panel1 As System.Windows.Forms.Panel
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ComboBox1 = New System.Windows.Forms.ComboBox()
Me.ComboBox1.FormattingEnabled = True
Me.ComboBox1.Location = New System.Drawing.Point(710, 117)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
Me.ComboBox1.TabIndex = 3
End Sub
#End Region
#Region " Member Variables "
Private mTable As DataTable
#End Region
#Region " Form and Control Events "
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub frmMain_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
End Sub
Private Sub s1()
End Sub
Private Sub s2()
End Sub
Private Sub s3()
End Sub
Private Sub s4()
End Sub
#End Region
#Region " Operations "
Private Sub s5()
End Sub
Private Sub s6()
End Sub
Private Sub s7()
End Sub
Private Sub s8()
End Sub
#End Region
#Region " API Events "
Private Sub s8()
End Sub
Private Sub s9()
End Sub
Private Sub s10()
End Sub
Private Sub s11()
End Sub
Private Sub s12()
End Sub
#End Region
Private Sub s13()
Dim divisor As Integer = 1
'[this is where i want the divisor to draw from the combobox]
'so instead of "Dim divisor As Integer = 1"
i want "Dim divisor As Integer = contents of combobox
End Sub
' i have no idea why this code appears here
Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
Private Class Item1
Public Sub s14()
End Sub
End Class
Private Class Item2
Public Sub s15()
End Sub
End Class
Private Class Item3
Public Sub s16()
End Sub
End Class
End Class
the sub i am working on is "s13()", but when i try to read from the combobox i get a blank.
exactly where to place the code that works as shown in my first example in the structure i show immediately above is unknown to me. i would have thought it would be much easier to read from a combobox, but i am stumped.
Given the names of your functions, it's difficult to tell exactly what you're trying to do. But you have a couple of options here. The function itself can access the value from the combo box if it's called while the combo box has a value in it, or the function can require the value as a function argument and whatever calls the function can pass the combo box's value.
For the first, it would look something like this:
Private Sub s13()
Dim divisor as Int32 = 1
If Int32.TryParse(Me.ComboBox1.Text, divisor) Then
' Perform your logic
Else
' The input wasn't a valid integer, maybe show an error?
End If
End Sub
Whereas the second approach might look like this:
Private Sub s13(ByVal divisor as Integer)
' Perform your logic
End Sub
And the code which calls that would need to get the value:
Dim divisor as Int32 = 1
If Int32.TryParse(Me.ComboBox1.Text, divisor) Then
s13(divisor)
Else
' The input wasn't a valid integer, maybe show an error?
End If
The main thing to note in all of this is that you should use Int32.TryParse() to determine if the inputted value in the combo box is actually an integer, and handle the error condition when it isn't.
You have to use the selected item :
If Int32.TryParse(ComboBox1.selectedItem, divisor) Then
MsgBox(ComboBox1.selectedItem)
Else
MsgBox("error" & ComboBox1.selectedItem)
End If
for anybody stuck with the same problem, here is the solution.
the code i had to work with is mammoth, so it would not let me pull in a combobox variable into any of the subs, esp as this is a multi-threaded prog. i knew, however, the solution had to be simple. and that is always something to keep in mind -- the solution is never that complicated, and you never need as much code as you think.
in this case i went down the path of a public variable,
Public Shared divisor As Integer
i placed this line underneath the very first line
Public Class frmMain
since there were other drop-down lists on the form that were clearly being drawn from, i went to the code associated with the button that initiated the steps to get the data from the server, just another button_click sub
if that sub pulled in the other combo boxes, then it had to grab the data in the one i wanted. all i did then was add this line of code to that button_click sub
divisor = ComboBox1.Text
since divisor is now a public variable, what was recorded in the button_click sub easily passes to another private sub that runs other routines. so anywhere in the code i want to use the variable 'divisor' all i have to do is mention it :)
if divisor > 0 then
'do something
end if