How to get info from another form...

R

Rob

Let's say you open Form1 that contains TabControl1

There are several tabs on TabControl1

Now you open a new Form2 that contains a User Control

How can you determine the Selected tab in Form1 from the User Control in
Form2 ?

Hope this is clear enough...

Thanks !
 
R

rowe_newsgroups

Let's say you open Form1 that contains TabControl1

There are several tabs on TabControl1

Now you open a new Form2 that contains a User Control

How can you determine the Selected tab in Form1 from the User Control in
Form2 ?

Hope this is clear enough...

Thanks !

IMO the proper way would be to expose the selected tab via a property
in Form1.

' Typed in message
Public Class Form1

Public Property SelectedTab As TabPage
Get
Return Me.TabControl1.SelectedTab
End Get
Set (ByVal value As TabPage)
Me.TabControl1.SelectedTab = TabPage
End Set
End Property

End Class

Public Class Form2

Public Sub MyMethod()
Dim f As New Form1()
f.Show()
Dim tp As TabPage = f.SelectedTab
MessageBox.Show(tp.Name)
End Sub

End Class

Thanks,

Seth Rowe
 
R

Rob

Thanks Seth,

But I am getting an error in in the Set statement...

It says "TabPag is a type and cannot be used as an expression"

Rob
 
R

Rob

Hmmm...

My TabPage was dynamically added (which I did not state)...so the problem
is probably on my end.
 
R

rowe_newsgroups

Thanks Seth,

But I am getting an error in in the Set statement...


It says "TabPag is a type and cannot be used as an expression"

Rob

That should say Me.TabControl1.SelectedTab = value

Like I said - I typed that in the message to just give you an idea of
how it should go - and not necessarily a working solution.

Thanks,

Seth Rowe
 
R

rowe_newsgroups

Hmmm...

My TabPage was dynamically added (which I did not state)...so the problem
is probably on my end.






My TabPage was dynamically added (which I did not state)...so the problem
is probably on my end.

I shouldn't matter - after all every control is both dynamically
created and added in the InitializeComponent() method. The problem is
my poor "air coding" which had a typo. Also, if you don't plan on
selecting a different tab from Form2, you should probably just make
the property readonly and only expose the Get accessor.

Thanks,

Seth Rowe
 
R

Rob

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
 
R

rowe_newsgroups

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
 
R

rowe_newsgroups

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 -

I forgot to answer this in my last post...
Is there a way to make all "open instance" form data Public ?

Yes, check out the control's modifier property - you can change it
from private to public.
If so, is this a bad idea ?

Yes! IMO you should only give access to just the fields you need to
expose. If you fully expose TextBox1 on Form2, what happens to the
rest of you program if some other form calls this:

Form2.Instance.Controls.Remove(Form2.Instance.Textbox1)
Form2.Instance.Textbox1.Dispose()

For safeties sake, I highly recommend you following the property
pattern and not just set the modifers to public.

Thanks,

Seth Rowe
 
R

Rob

Seth,

Thanks so much again... I am still trying to digest it... but...

Regarding... below...

Should the following be "Public" ? Otherwise I am getting object reference
errors...

Private Sub New()
InitializeComponent()
End Sub

Thanks,
Rob

------------------------------


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
 
R

rowe_newsgroups

Seth,

Thanks so much again... I am still trying to digest it... but...

Regarding... below...

Should the following be "Public" ? Otherwise I am getting object reference
errors...

Private Sub New()
InitializeComponent()
End Sub

Thanks,
Rob

------------------------------

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

































- Show quoted text -

No - if it's public that would allow outside object to create your
form. The point of the singleton pattern is to allow only the Instance
property to create the form.

What "object reference errors" are you getting? I'm guessing you are
trying to instantiate Form2? If so you are missing the point of the
singleton pattern. Instead of instantiating form2 (Dim f as new
Form2()), you should be accessing it through the instance property
(Form2.Instance.Text = Hello World!)

Thanks,

Seth Rowe
 
R

Rob

Hi Seth,

I made some small changes that appear to make things "work".... I hope
these changes are OK...

Thank you once again for exposing me to a different way to accomplish things
!

You are amazing !

Rob


Public Class JobOpSelection
Private Shared FInstance As JobOpSelection = Nothing
Private Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub

Public Shared ReadOnly Property Instance()
Get
If (FInstance Is Nothing) Then FInstance = New JobOpSelection()
Return FInstance
End Get
End Property

Public Property ContentTextBox1() As String
Get
Return Me.TextBox1.Text
End Get
Set(ByVal value As String)
Me.TextBox1.Text = value
End Set
End Property

Public Property CntJobOp() As String
Get
Return Me.txtCntJobOp.Text
End Get
Set(ByVal value As String)
Me.txtCntJobOp.Text = value
End Set
End Property
 
R

rowe_newsgroups

Glad I helped! What you have looks good to me - though I didn't look
at it too close. Below is a link to one of Jon Skeet's articles that
talks about a better implementation of the singleton pattern. The
basic pattern I showed you above should be fine for your project, but
for multithreaded apps I seem to always use the pattern Jon shows in
the link.

http://www.yoda.arachsys.com/csharp/singleton.html

Thanks,

Seth Rowe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top