I know this question might have been asked a zillion times,
I am just starting out in vb.net, I used vb6 and thought of upgrading to the new language.
I learnt lots of new stuff about .net and some things are similar to vb6 and some stuff are not.
I came to forms, and geez I found myself inside a new unexplored ocean, gone are the simplicty of form.show()
and acessing a forms property with the simplicity of vb6.
My problem is this, I have 2 forms, formA and FormB.
I load FormA, now imagine FormB as an options form that the changes made to formB will reflect on FormA. eg. on FormB I have an option called Background Color, I want that when the user chooses a color on formB, it will show on formA.
The main form (the one that loads first is FormA). and from FormA
I load FormB.
I used the command,
Dim variablename as FormA
in FormB and then typing
variablename.bgColor bla bla
but to no avail.
Can somebody help me, or redirect me to a good online tutorial on forms,which covers this aspect, and is intended mainly for beginners or intermediate programmers.
I am a hobby programmer, this is not my full time job so please remeber this when answering to this thread, that I am not a guru in this lanquage.
There are several points here. Look up MSDN Help on Inheritance and search this forum for the many threads on this subject.
As a quick start for you, use the Sub Main of a module as your startup object.
In the module code
VB Code:
Public frm1 As New FormA
Public Sub Main()
Application.Run(frm1)
End Sub
In FormA put the following code in the appropriate event
VB Code:
Dim Frm2 As New FormB
Frm2.ShowDialog
Put the following code in the appropriate event of FormB
VB Code:
frm1.BackColor = Color.Blue
In your posted code you nearly created a separate instance of FormA, but you omitted to use the NEW keyword.
When you show a form in your project runtime, what you are showing is an INSTANCE (exact copy) of the form you designed, so if you are not careful, you might create several copies when you only intended to create one.
I've got a feeling we will be hearing from you again, but don't be shy
Taxes
The more I learn about VB.NET the more I like dBaseIII Plus
The foregoing, whilst believed to be correct, is given without guarantee as to it's accuracy and entirely without recourse. You are required to decide for yourself whether or not it is suitable for your purposes and no liability for loss of any nature can be entertained.
Hi Taxes, good morning to you and to your dog (Paverotti?)
Good morning also to Lamer, obviously.
I agree with Taxes at 99%, but there is a particular that I would change:
VB Code:
Public frm1 As FormA
Public Sub Main()
frm1 = New FormA
Application.Run(frm1)
End Sub
I had an experience, the day before yesterday, that teached me this is the best way. I'm not completely sure, but this is what I undestood it happened:
I used the the way as Taxes propose. My starting form had a procedure in LOAD event that used an Array declared some lines below in the same module. I had an error! The Array was not available when the form load routine was fired. Probably all declarations are performed and then are performed the Sub, so if you use a mixed instructions like:
Dim Pippo as NEW frmPippo
you fire the builder (NEW) and unchained the load event of the form before to be sure all declarations are performed (excuse for my confused english)
I resolved my problem separating the declaration from instanciation(correct?).
This is my field experience, so I could be wrong and everithing I said is only what I imagine it happens. I 'm not sure about the meaning of what I observed. Do you have some opinions about?
Thanks for your help, both of you, but I tried the solutions, that you gave me but to no avail.
I am trying this with textboxes.
I.E.
Form A loads first, then the user clicks a button and form B loads.
On form B I have a combo box, and the user selects a value.
When the user press an OK button on Form B, I want the value of the combo box on form B to be copied to a textbox on Form A.
I tried your solution taxes, obviously modifying the bg and names, of the forms, but to no avail.
Originally posted by d_lamer2003 Thanks for your help, both of you, but I tried the solutions, that you gave me but to no avail.
I am trying this with textboxes.
I.E.
Form A loads first, then the user clicks a button and form B loads.
On form B I have a combo box, and the user selects a value.
When the user press an OK button on Form B, I want the value of the combo box on form B to be copied to a textbox on Form A.
I tried your solution taxes, obviously modifying the bg and names, of the forms, but to no avail.
Hi,
Sorry, I should have told you to set the Modifiers property of the combobox to PUBLIC. You do this at design time.
Taxes
The more I learn about VB.NET the more I like dBaseIII Plus
The foregoing, whilst believed to be correct, is given without guarantee as to it's accuracy and entirely without recourse. You are required to decide for yourself whether or not it is suitable for your purposes and no liability for loss of any nature can be entertained.
Originally posted by alextyx Hi Taxes, good morning to you and to your dog (Paverotti?)
Good morning also to Lamer, obviously.
I agree with Taxes at 99%, but there is a particular that I would change:
VB Code:
Public frm1 As FormA
Public Sub Main()
frm1 = New FormA
Application.Run(frm1)
End Sub
I had an experience, the day before yesterday, that teached me this is the best way. I'm not completely sure, but this is what I undestood it happened:
I used the the way as Taxes propose. My starting form had a procedure in LOAD event that used an Array declared some lines below in the same module. I had an error! The Array was not available when the form load routine was fired. Probably all declarations are performed and then are performed the Sub, so if you use a mixed instructions like:
Dim Pippo as NEW frmPippo
you fire the builder (NEW) and unchained the load event of the form before to be sure all declarations are performed (excuse for my confused english)
I resolved my problem separating the declaration from instanciation(correct?).
This is my field experience, so I could be wrong and everithing I said is only what I imagine it happens. I 'm not sure about the meaning of what I observed. Do you have some opinions about?
Hi alextyx,
Just one point - my dog is named "PAV" because he is a Rotti
I have tried to duplicate your problem but can't.
I Declared a one dimension array in the space between subs halfway down the form, (which I presume is what you mean although I think that is untidy) with the Dim keyword.
I filled the array with values in the form_Load event and displayed the contents of one element of that array in a textbox. No problems at all. Are you sure you did not declare the array WITHIN a sub????
Taxes
The more I learn about VB.NET the more I like dBaseIII Plus
The foregoing, whilst believed to be correct, is given without guarantee as to it's accuracy and entirely without recourse. You are required to decide for yourself whether or not it is suitable for your purposes and no liability for loss of any nature can be entertained.
here is the code to a sample MDI application I wrote for another thread, it's fairly simple and straight forward and shows how to access the properties and methods of the child forms from the parent and also the parent from the children.
and this is my actual code under which I let you see the declaration of the 'damned' Array
VB Code:
Module Module1
Sub Main()
FStart = New FrmStart
Application.Run(FStart)
End
End Sub
Public Splash As FrmSplash
Public FStart As FrmStart
'here some others declaration omitted
' ----------------- Dichiarazioni di Array -----------------------------------
Public ArrSettaggi(1) As String
This is the routine of load event:
VB Code:
Private Sub FrmStart_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
GIN.PblSubCaricaSettaggiOValoriDiDefault()
GIN.Splash = New FrmSplash
Splash.Size = Me.Size
Splash.Timer1.Start()
Splash.ShowDialog()
Me.Calc.Show()
End Sub
This is the public sub called in the load event. It extracts setting from a file (Text) that exists!
VB Code:
Public Sub PblSubCaricaSettaggiOValoriDiDefault()
'Assegna all'ArrSettaggi i valori contenuti nel file di inizializzazione. Qualora nn sia possibile, fa
' in modo di assegnargli dei valori di default
If System.IO.File.Exists("C:\AEASRL\GIN\INIGIN.TXT") Then
Dim Leggi As IO.FileStream
Dim Lettore As IO.StreamReader
Try
Leggi = New IO.FileStream("C:\AEASRL\GIN\INIGIN.TXT", IO.FileMode.Open, IO.FileAccess.Read)
Lettore = New IO.StreamReader(Leggi)
'leggi.Length
Dim temp As Byte = 0
Do Until temp >= ArrSettaggi.Length
If Lettore.Peek < 0 Then 'Se <0, nn ci sono più byte da leggere. Fine file!
'Se qui, il file è finito inaspettatamente, cioà risulta avere meno righe del previsto
MsgBox("Il file: " & Leggi.Name & " è risultato avere meno righe del previsto. Verranno caricati i valori di default")
PblSubAssegnaValoriDiDefault() 'Si assegnano i valori di default
Else
'Se qui, per adesso va tutto bene. Si continua a leggere
ArrSettaggi(temp) = Lettore.ReadLine
temp += 1
End If
Loop
Leggi.Close()
Lettore.Close()
Catch ex As Exception
MsgBox(ex.Message)
PblSubAssegnaValoriDiDefault()
End Try
Leggi = Nothing
Lettore = Nothing
Else
MsgBox("Il file di configurazione non è stato trovato")
PblSubAssegnaValoriDiDefault()
End If
End Sub
This is what I can read in the window of the exception:
************** Testo dell'eccezione **************
System.NullReferenceException: Riferimento a un oggetto non impostato su un'istanza di oggetto.
at GIN.Module1.PblSubAssegnaValoriDiDefault() in E:\alex\VBNet\Progetti\Gin.Net\Beta3.0\CosePubbliche.vb:line 678
at GIN.Module1.PblSubCaricaSettaggiOValoriDiDefault() in E:\alex\VBNet\Progetti\Gin.Net\Beta3.0\CosePubbliche.vb:line 710
at GIN.FrmStart.FrmStart_Load(Object sender, EventArgs e) in E:\alex\VBNet\Progetti\Gin.Net\Beta3.0\FrmStart.vb:line 468
As you can see, it's no so direct!
Anyway the problem disappear when I use the second way to declare and istance the form, so I think the problem is something similar to that I figured, but this is a work in progress, I hope you or others could help me to undestand. Obviously if you don't see the problem it's very more difficult, I know.
Thanks anyway
It looks like you may have two instances of FrmSplash lying around.
Are you sure you are running
VB.NET (2002 or 2003) and not a Beta version???
Taxes
The more I learn about VB.NET the more I like dBaseIII Plus
The foregoing, whilst believed to be correct, is given without guarantee as to it's accuracy and entirely without recourse. You are required to decide for yourself whether or not it is suitable for your purposes and no liability for loss of any nature can be entertained.
FrmSplash is good as it is. It is instanciated later and then disposed.
For double FrmStart: I rewrote my code in order to reproduce the exception and so.... there was a declaration more than it's necessary. I noted that, after I posted, so I corrected and try again with the same result.
The code worked properly also when FrmStart was the starting object of the project. Only when I decided to upgrade this old project, using a more convenient way to run it, it happened the trouble.
And it disappeared at the moment I used the way in two times:
Dim a New on separate lines.
I'll try to investigate deeply on this problem, writing dummy code to reproduce it in an easier way, if possible......when I'll have some more time to spend
Ok Taxes, now I have a more clear idea, but now I have some problem to explain it in english.
I try to explain what it seems happens:
Basically my first idea was good, but following step by step the code progress I noted that when you instance a form there is only an initialization of component, then code come back to following lines....and FormLoad??? It arrives, but after a lot of other lines were executed and anyway before application.run were executed, so it confirm that instancing a form run its load event. The strange behaviour is that there is a gap between 'initialize component' and 'Load'. In this gap many other lines of code are executed. I found the exact (it's repetitive) point in which load event of FrmStart were executed (about 2 lines above the declaration of the array), so I tried to move the array declaration a few lines above and problem disappears (as I presumed)!!!
I don't know if my explanation is sufficiently clear....I use the terms I know, not surely the most appropriate.
Anyway now is also clear why your test failed. You must add a lot of instructions before to reach the critical mass!
I think this is a good thing to know
Obviously I could have not considered something, I'm not completely sure about what I'm saying, so if some more expert friend wants to give his help to Taxes and me, or we have to do the entire job by ourselves?
Uffff...it was an hard work, but now I have quite clear ideas on the subject
I believed formload shoudn't fire only instanciating form, so I realized that a Timer starts in my form1. Because its 200 ms intervals is not sufficient to wait all declaration in the module were done, i have the error. OK, i can put Timer enable property to false until ....some other event. Now that I have understood the problem I have a lot of solution!
Some months ago, another developer (20 years professional experience,various microsoft certified, etc... not a silly electronics like me ) saw my way to declare and instance form exactly we are disccussing about. He said to me: 'Very bad habit, trust me!'. Because normally I'm not happy when someone say to me 'Do something' without an explanation, I continued to work exactly as before
Now I realize (I'm new to all the High level language's world, included OOP problems), because I crash my face on the problem, that instancing is not something as: I do it now, so I've not to do it later!
It inflates a sort of life in your object. Now I believe it's a good idea to instance a form when it's the moment to use it, and when is natural that everything it needs to work has to be available.
I studied two examples that I hope could be useful:
The first is an example of how position of declarations could make an application run or fail
The second is an example of how an application can autostart
Both project are setted to start from sub main
Project n.1 is composed by an empty form and a module
VB Code:
Public Class Form1
Inherits System.Windows.Forms.Form
Dim pluto As Byte = Byte.Parse(Pippo)
#Region " Codice generato da Progettazione Windows Form "
End class
Module Module1
' ------------ It works begin ------------------------------
'Public F1 As Form1
'Sub main()
' F1 = New Form1
' Application.Run(F1)
'End Sub
'Public Pippo As String = "0"
' ------------ It works end ------------------------------
' ------------ It works n.2 begin ------------------------------
'Public Pippo As String = "0"
'Public F1 As New Form1
'Sub main()
' Application.Run(F1)
'End Sub
' ------------ It works n.2 end ------------------------------
' ------------ It fails begin ----------------------------
Public F1 As New Form1
Sub main()
Application.Run(F1)
End Sub
Public Pippo As String = "0"
' ----------- It fails end -----------------------------
End Module
The second is composed by a module an two forms. The form2 contains a textbox (textbox1) that change its forecolor every time text changed. The application run and work only instantiating form1:
VB Code:
Module Module1
Dim f1 As New Form1
Sub main()
End Sub
End Module
Public Class Form1
Inherits System.Windows.Forms.Form
Dim FlagLanciato As Boolean = Autostart()
#Region " Codice generato da Progettazione Windows Form "
Private Function Autostart() As Boolean
Dim f2 As New Form2
f2.ShowDialog()
End Function
End Class
Public Class Form2
Inherits System.Windows.Forms.Form
#Region " Codice generato da Progettazione Windows Form "
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Static C As Byte = 0
If C = 0 Then
Me.TextBox1.ForeColor = Color.Red
C = 1
Else
Me.TextBox1.ForeColor = Color.Green
C = 0
End If
End Sub
End Class
You can run application and form2 appears and forecolor change as expected.
Obviously is not illegal to use all 'Dim fx as new Frmx' in the starting module, but now I've seen this I'll not do it again....but is only my opinion!
I see. It only fails when you assign a value to Pippo AFTER the instantiation of F1. In
' ------------ It fails begin ----------------------------
Public F1 As New Form1
Sub main()
Application.Run(F1)
End Sub
Public Pippo As String = "0"
' ----------- It fails end -----------------------------
The program flow is exactly as listed, so that when F1 is instanced, Pippo has not been given a value and you get a Null Reference exception in F1 at
Dim pluto As Byte = Byte.Parse(Pippo)
However, in
' ------------ It works n.2 begin ------------------------------
'Public Pippo As String = "0"
'Public F1 As New Form1
'Sub main()
' Application.Run(F1)
'End Sub
' ------------ It works n.2 end ------------------------------
Pippo is declared with a value BEFORE F1 is processed.
In
' ------------ It works begin ------------------------------
'Public F1 As Form1
'Sub main()
' F1 = New Form1
' Application.Run(F1)
'End Sub
'Public Pippo As String = "0"
' ------------ It works end ------------------------------
The program flow is such that the Sub Main is processed AFTER Pippo has been declared and FI instance is only processed AFTER the NEW keyword.
Conclusions:
Either do it as you suggest and Declare the variable F1 without creating the instance of Form1 at that time; OR
Make sure you declare and fill all public variables BEFORE creating instances of forms in which those variables will be used.
Many thanks for all your effort. It is good to be aware of possible problems.
Last edited by taxes; Jul 4th, 2004 at 12:34 PM.
Taxes
The more I learn about VB.NET the more I like dBaseIII Plus
The foregoing, whilst believed to be correct, is given without guarantee as to it's accuracy and entirely without recourse. You are required to decide for yourself whether or not it is suitable for your purposes and no liability for loss of any nature can be entertained.
Exactly! If you know how it works you can avoid problems, but someone, like me until few days ago, could not have an exact perception of what to instantiate means. So, perhaps, it could be a better habit to do it only when is the moment to use the object, but this is not a fixed rule. It's obvious that an expert developer could work in both ways, because he knows his instruments. For newbies (first is me!), better avoid risks, I think! Thanks for your help, Taxes!