Seth,
I think I am missing a really "big" concept regarding scope of variables and
instances...
In your example, are you not creating a "new" instance of Form1 when you
call the sub in Form 2 ?
Therefore, aren't you always going to get the default value of whatever
control's property you are returning ?
I want to know the selected tab page of a form whose instance already
exists....
It appears that I am constantly boxing myself into a corner (I can't get
there from here)....
(In MS Access, as long as the form was open, you could issue
Forms.frmWhatever.contol and alway get your answer.)
For example...
Let's say you begin in Form1
There is a Button1 on Form1
Button1 opens an instance of Form2
Button1 also adds a User control to Form2 (This User Control contains a
ButtonU)
On Form2 there is a TextBox1 and a Panel containing the User Control
This is where I run into the dead-end...
From the ButtonU in the user control I want to update the Textbox1 on Form2,
but I cannot appear to "get back" to update that control (i.e.,
frmForm2.TextBox1.Text is not declared) Again, I do not want to update a
"new" instance of Form2, I want to update an existing instance (the one that
was opened from Button1 on Form 1).
Furthermore, I may also want to update somthing in Form1 from within the
User control in Form2, but those "existing" controls appear to be
inaccessible as well.
Is there a way to make all "open instance" form data Public ? If so, is
this a bad idea ?
Also, let me say thanks again for all your input into this newsgroup. You
are a tremendous resource !
Rob
- Show quoted text -
Forms in Access are what called singleton forms. Only one instance can
be open at a time - therefore you can always use the
Forms.MyForm.MyField. In .Net you can create any number of the same
form which means you can't use the Forms.MyForm.MyField syntax. Here's
why:
Consider this code which creates 25 Form1's and assigns a value to
it's text property
For i As Integer = 0 to 24
Dim f As New Form1()
f.Text = String.Format("Form Number {0}", i.ToString())
f.Show()
Next i
Now that we have 25 forms, which one will return it's text value when
we do this (if it was a valid statement)?
MessageBox.Show(Forms.Form1.Text)
You see, there is no way for the framework to know which form you
wanted to grab, so this statement is not included in the framework.
In your case you have two options, one is to create an instance of
Form1 and keep a reference to it by using a property or variable. For
example:
Public Class Form2
Dim MyTrackedForm1 As Form1
Public Sub New()
InitializeComponent()
MyTrackedForm1 = New Form1()
' Set other properties for MyTrackedForm1
End Sub
Public Sub Button_Click(.....)
MessageBox.Show(MyTrackedForm1.Text)
End Sub
End Class
Now you create an instance of Form1 in the beginning of an instance of
Form2, and store a reference to it in the MyTrackedForm1 variable.
Then any time you need to access one of it's properties/methods you
just use the MyTrackedForm1 variable to access the instance you
created. This approach works great when you only have one form
accessing an instance of Form1, but if you have multiple different
forms (like a form2, form3, form4, etc) all trying to access a certain
Form1's members, you would have to use a global variable (which I
dislike) and remember to only use it.
This global variable also doesn't stop Form1 from being instantiated
multiple times, but this next approach does. What we are going to do
is use the Singleton design pattern and make it so that only one Form1
can exist at a time, and all requests will go to that certain Form1.
If you want to know more about Singleton I would recommend you do some
searching on google or wikipedia - others have done a better job
explaining it's strength and weaknesses better than I could. Anyways,
basically we want to make it so that noone can instantiate our form
directely - we do this with a private (or protected) constructor like
so:
Private Sub New()
InitializeComponent()
End Sub
Now that no outside objects can create Form1 we need to give them a
way to access Form1, we do this with a variable/property pair. And
since we want this property to be visible to everyone without needed
Form1 to be instantiated, we use a shared property and variable.
Private _Instance As Form1
Public Property Instance As Form1
Get
If _Instance Is Nothing Then
_Instance = New Form1()
' Set other properties if necessary
End If
Return _Instance
End Get
End Property
If you look the property checks to see whether or not Form1 is already
created in the get accessor. If it is, it return the current Form1, if
not however it creates a new instance of Form1 and return's it.
Now to use this all you need to do is use this Singleton pattern on
any form you want to be a single instance form. Then just expose any
necessary fields by use of properties. From what I can tell you want
to have a singleton instance of Form2 and expose the text property of
it's textbox1. This basic form design should be:
Public Class Form2
Private _Instance As Form2
Public Readonly Property Instance As Form2
Get
If _Instance Is Nothing Then _Instance = New Form2()
Return _Instance
End Get
End Property
Private Sub New()
InitializeComponent()
End Sub
Public Property TextBoxText As String
Get
Return TextBox1.Text
End Get
Set (ByVal value As String)
TextBox1.Text = value
End Set
End Property
End Class
Then in the Button1 click event in Form1 you can just do this:
Form2.Instance.Controls.Add(New UserControl1)
Form2.Instance.ShowDialog(Me)
And in the ButtonU click event in the UserControl you can do this:
Form2.Instance.TextBoxText = "My new value"
And you should be set!
Thanks,
Seth Rowe