I understand its possible to open the "default instance" of a form in vb.net by calling NameOfTheForm.show()
How do I pass an object to the default form instance so i can work on the object and use it to populate the forms Text boxes?
I've tried to add a parameter to the frmNames New method but I'm not sure how then to open the form. The old style instantiate an object works:
Dim DetailsForm As New frmOrder(oOrder)
DetailsForm.Show()
But I'm used to using the :
frmOrder.show
syntax.
Should I use the top method or should I use the bottom method and have a public property on the form to accept the Object?
Have a missed a better method of doing this?
Thanks
Your calling method should use your first option
'Careful about declaring this in a sub, because when that sub ends, the form might get closed.
'It might be best to declare this as an instance var (aka form-level var)
Private DetailsForm As frmOrder
'this could go in an event handler, or anywhere
DetailsForm = New frmOrder(oOrder)
DetailsForm.Show()
You will need to add a constructor to your DetailsForm:
Private _oOrder as OrderType
Public Sub New(oOrder As OrderType)
'Best to save it to a private instance var and process it during Form_Load
_oOrder = oOrder
End Sub
Then when your Form_Load() runs, it can use your private instance var to fill your TextBoxes, like you want.
A second, but less eloquent approach would be to add a public property to the form and after you call .Show(), you can assign a value DetailsForm.OrderObject = oOrder, and then process the object that was passed-in.
The constructor approach is better because it can be "compiler checked"
If you really feel you must use default instance.
In Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.myObject = New Coffee("Breakfast Blend", 7)
Form2.Show()
End Sub
In Form2
Public myObject As Coffee
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Text = myObject.Name
TextBox2.Text = myObject.ID.ToString
End Sub
Related
In my second Form, I have a Collection of an Object which I add when I need.
When I want to access to the first Object in that Collection for example, from another Form. It returns me nothing: when I do form2.list.Count, I have 0. What I understood from this, is the Collection is Null.
But in the second form (the Form where I created that Collection), if I do form2.list.Count, I have the correct count and I have access to all the data.
I made sure that Collection was Public but still, I don't know where is the problem.
How can I solve this ?
Edit:
Public Class Form2
Public mycarlist As New carlist
Private Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
dim mycar as car
'I have other textbox but for simplicity, I only put one
mycar = new car(Me.TextBox1.Text)
mycarlist.Add(mycar)
' Here everything works, I have the correct count and brand
Form1.TextBox1.Text = mycarlist.count
Form1.TextBox2.Text = mycarlist(0).brand
Me.Close()
End Sub
End Class
And it's from this Form (Form1) that I want to access to this list:
Public Class Form1
Private Sub testbt_Click(sender As Object, e As EventArgs) Handles tesbt.Click
Me.TextBox3.Text = Form2.mycarlist.Count
'For example a Property that I want to print
Me.TextBox4.Text = Form2.mycarlist(0).Brand
End Sub
Private Sub openform2_Click(sender As Object, e As EventArgs) Handles openform2.Click
Form2.Show()
End Sub
End Class
In the Form1, the TextBox1 returns me 0
And when the program will execute this line Me.TextBox2.Text = Form2.mycarlist(0).Brand, I have this error:
System.ArgumentOutOfRangeException from carlist.
Your assertion that the collection is null is incorrect because otherwise you'd receive a NullReferenceException to the effect of:
Run-time exception (line -1): Object reference not set to an instance of an object.
VB.NET does some funky stuff when it comes to accessing forms. My guess is that you're attempting to get the wrong instance of Form2 and VB.NET is creating a new instance of the Form behind the scenes.
Could you show how it is that you're creating Form2? It may be as simple as referencing the correct instance of the Form. E.g.:
Private frm2 As Form2 = New Form2()
' user adds item(s) to list
frm2.list.Count
How I call generic Of T sub choose form string?
How to better way code like this?
Sub ShowAddfrm(Of T As {Form, New})()
dim frm as new T 'New Form
frm.Show()
End Sub
Private Sub btnAddProblemfrm_Click(sender As Object, e As EventArgs)
Dim keys As String = CType(sender, Button).Name.Replace("btnAdd", "")
If keys = "frmShowProblem" Then
ShowAddfrm(Of frmShowProblem)()
End If
If keys = "frmUser" Then
ShowAddfrm(Of frmUser)()
End If
End Sub
Try this overloaded method, allowing both a Form reference and string parameter.
You can pass the default instance of a Form, naming it directly:
ShowAddfrm(Form2)
or the Form's name:
ShowAddfrm("Form2")
or using a Control's Tag property (or any other source) in an event handler:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ShowAddfrm(DirectCast(sender, Control).Tag.ToString())
End Sub
There's a difference:
if you use pass the instance of a Form, only that instance will be created. Meaning, if you use a Button to show the Form and you press the Button multiple times, no new instances will be created. If you close the Form, then a new instance will be shown.
If you use the string version, each time you call this method, a new instance of the Form will be shown, so you can have multiple Forms on screen.
The string version uses Activator.CreateInstance to generate a new instance of a Form using it's name.
Sub ShowAddfrm(Of T As {Form, New})(ByVal form As T)
form.Show()
End Sub
Sub ShowAddfrm(formName As String)
Dim appNameSpace = Assembly.GetExecutingAssembly().GetName().Name
Dim form = CType(Activator.CreateInstance(Type.GetType($"{appNameSpace}.{formName}")), Form)
ShowAddfrm(form)
End Sub
I am getting a an Null reference exception when trying to add an item to a listbox in a different form.
This is my error at run time.
An unhandled exception of type 'System.NullReferenceException'
occurred in ... Additional information: Object reference not set to an
instance of an object.
I am trying to connect the Mainform by initializing it at the top of the class of the secondForm. after I have my data i want to add it to a listbox it the mainform.
Public Class FormHairdresser //The second form
Dim varMainForm As FormMain //connecting the forms ?
Private Sub btnAddHairdresser_Click(sender As Object, e As EventArgs) Handles btnAddHairdresser.Click
hairdresser = HairdresserChoices(HairdresserID) // get the data
varMainForm.lstListBox.Items.Add(hairdresser) //Run time error breaks here.
All i had to to was write the form name instead of ininalised variable.
FormMain.lstListbox.Items.Add("item")
Instead of
Dim varMainForm As FormMain
varMainForm.ListBox.Items.Add("item")
You cannot simply create a new instance of your main form (as has been suggested and expect that to work, you need an actual reference to the mainform that you have created. To help you see the logic involved;
Create a new Winforms project. In the default Form1 add a textbox and a button.
Now add a new form to this application (you can leave it with its default name of Form2. To this form add a TextBox (call it myTextBox) and a button.
Now go back to your first form and doubleclick the button to access the click handler in code. Add the following:
Dim frm as New Form2
frm.Show
Press f5 and click the button and you'll see a new form 2. So far so good.
Now open up the code for Form2 and add the following code so that it ends up looking like this:
Public Class Form2
Private frm As Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
frm.TextBox1.Text = myTextBox.text
End Sub
End Class
build, press f5 and click the button on form1, in the new form2 enter some text in the text box and click the button, you get your null reference exception. The reason you get this is because at the moment the private field frm inForm2 refers to Nothing.
Now open up the code in Form2 and add a constructor and the following code so that it ends up looking like this:
Public Class Form2
Private frm As Form1
Public Sub New(byval frm1 As Form1)
'first we should make sure that we have a parameter to play with
If Not IsNothing(frm1) Then
frm = DirectCast(frm1,Form1)
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
frm.TextBox1.Text = myTextBox.text
End Sub
End Class
Finally go back to your first forms buttonclick handler and change the code slightly so that it looks like this;
Dim frm as New Form2(Me)
frm.Show
Build and run your application, now when you enter text into the textbox in form2 and click the button it will appear in the textbox in Form1.
The reason why this happens is because you have passed an actual reference to the form1 that was originally created when the application started to form2. By casting that reference to your private field used to represent form1 in form2 you can then use it to properly refer to things on form1. This is a very simple concept but one which you need to learn before you will make progress programming.
the Problem is with your initialization of the formmain.with out proper initialization the object you are creating is nothing other than Null.To avoid this we use New Operator.The New operator can often be used to create the instance when you declare it.
So the initialization will look like
Dim varMainForm As New FormMain
Hope this Helps.For more Reference Object Initialization Errors
update:
Dim varMainForm As FormMain //connecting the forms ?
Private Sub btnAddHairdresser_Click(sender As Object, e As EventArgs) Handles btnAddHairdresser.Click
hairdresser = HairdresserChoices(HairdresserID) // get the data
varMainForm = New FormMain
varMainForm.lstListBox.Items.Add(hairdresser) //Run time error breaks here.
Try This.
Public Class FormHairdresser //The second form
Private Sub btnAddHairdresser_Click(sender As Object, e As EventArgs) Handles btnAddHairdresser.Click
Dim varMainForm As FormMain
hairdresser = HairdresserChoices(HairdresserID)
varMainForm.lstListBox.Items.Add(hairdresser)
In visual basic I have a label set to increment every time a button is clicked. However when I close and reopen the form the label goes back to default value. Is there a way to keep this label the same it was before I closed the form? Thanks
When you close the form instance every local object kept by the form is disposed (destroyed). When you show again the form a new instance of the form class is created but the objects are all initialized to their default values. So you have lost your current value.
A possible workaround is to have a Shared variable inside the form class that keeps the count.
Shared variables are not destroyed with the class instance but are available for every instance of the class with their current value
You use this value to initialize your label in the form constructor with the current value of your clicks
Public Class Form1
Private Shared clickCount As Integer
Public Sub New()
InitializeComponent()
myLabel.Text = Convert.ToString(clickCount)
End Sub
' you could also use Form1_Load event if you prefer
' Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Label1.Text = Convert.ToString(clicksCount)
' End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
clicksCount += 1
myLabel.Text = Convert.ToString(clicksCount)
End Sub
End Class
Keep in mind that this approach use the same variable (clickCount) for every instance of Form1 you create.
I have a BackgroundWorker that is used to carry a time consuming process while a form is shown. The form and the BackgroundWorker are in separate classes, and when the BackgroundWorker has finished what it has to do, I need to carry out some basic actions on the form.
However, the below does not work and produces the warning Reference to non-shared member requires an object reference.
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
mainForm.btnCancel.Enabled = False
mainForm.btnFinish.Enabled = True
End Sub
I researched the warning and it suggested that I had to ensure the object mainForm was declared, which for this scenario seems odd from the get go. Regardless, I changed my code to this, and the warning disappeared, but as suspected, it doesn't work. It seems that a new instance of the form would be referenced, which is not what I require.
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
Dim objForm As New mainForm
objForm.btnCancel.Enabled = False
objForm.btnFinish.Enabled = True
End Sub
Can someone please tell me how I can interact with a form from a BackgroundWorker? Thanks.
The problem is not that you need to declare a new mainForm object. The problem is that you need a reference to the right mainForm object. Since it is possible to create any number of mainForm objects, you need a reference to the particular mainForm object that you want to modify. Remember, mainForm is the class (a type of object). It is not, itself, an object.
The simplest way fix this would be to give a reference to the mainForm object to the class that is performing the work, like this:
Public Class MyBusiness
Public Property TheMainForm As mainForm
' ...
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
TheMainForm.btnCancel.Enabled = False
TheMainForm.btnFinish.Enabled = True
End Sub
End Class
Then, before starting the work, you need to make sure you set the TheMainForm property. For instance, something like this:
Dim business As New MyBusiness
business.TheMainForm = Me
business.DoWork()