Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Go Back  Xtreme Visual Basic Talk > > > Accessing Controls on one Form from another Form


Reply
 
Thread Tools Display Modes
  #1  
Old 09-02-2004, 04:11 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default Accessing Controls on one Form from another Form


It would seem to me that one of the most difficult skills to master in VB.Net is accessing the controls on one Form from another Form. The Global scope of Forms in Access Basic and VB6 is not supported in .Net. (I may have got the vocabulary wrong but you know what I mean.)

Having already investigated this for some time I have discovered how to write FROM Form1 to Form2 and to write TO Form1 from a Sub in a Module called from Form1.

The article at:

http://msdn.microsoft.com/library/de...adingToNET.asp

and posts from MKoslof have been a great help.

BUT. How do I write TO Form1 FROM Form2?

To illustrate the point and provide a starting place for discussion: -

I worked through the illustration in the MSDN article. So I have: -

Form1 which contains three buttons and one textbox. And
Form2 with a single textbox and one button
All controls have their default names.

The code behind Form1 is

Code:
Public Class Form1
    Inherits System.Windows.Forms.Form
     Dim myForm2 As New Form2

" Windows Form Designer generated code "

     Private Sub Button1_Click(ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button1.Click
          myForm2.CustomerName = "Fred"
          myForm2.Show()
     End Sub

     Private Sub Button2_Click(ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button2.Click
          'Get contents of Form2.TextBox1
          MessageBox.Show(myForm2.CustomerName)
          'Write to Form2.TextBox1
          myForm2.CustomerName = "Joe"
     End Sub

     Private Sub Button3_Click(ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button3.Click
          Call DoSomething(Me)
     End Sub
End Class
The code behind Form2 is

Code:
Public Class Form2
     Inherits System.Windows.Forms.Form

" Windows Form Designer generated code "

     Public Property CustomerName() As String
          Get
               Return TextBox1.Text
          End Get
          Set(ByVal Value As String)
               TextBox1.Text = Value
          End Set
     End Property

     Private Sub Button1_Click(ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button1.Click

          'How can I write to Form1.textbox1 from here
          '===========================================

     End Sub
End Class
The code in Module1 is

Code:
Module Module1
     Public Sub DoSomething(ByRef f As Form1)
          'Write to Form1.TextBox1
          f.TextBox1.Text = "Hi From the Module"
     End Sub
End Module
The question is. How do I write to Form1.TextBox1 FROM a button press on Form2?

There is a solution.

The MSDN article proposes the use of the following code at the start of each Form’s code.

Code:
Private Shared m_vb6FormDefInstance As Form1
     Private Shared m_InitializingDefInstance As Boolean

     Public Shared Property DefInstance() As Form1
          Get
               If m_vb6FormDefInstance Is Nothing _
                   OrElse m_vb6FormDefInstance.IsDisposed Then
                    m_InitializingDefInstance = True
                    m_vb6FormDefInstance = New Form1
                    m_InitializingDefInstance = False
               End If

               DefInstance = m_vb6FormDefInstance
          End Get

          Set(ByVal Value As Form1)
               m_vb6FormDefInstance = Value
          End Set

     End Property
It is then possible to refer to controls on the Form like

Code:
Form1.DefInstance.Txtbox1 Text() = "Hello World"
In other words, this gives the form global scope. Surely this is not in keeping with OOP programming.

Does anyone else use the “DefInstance” technique?

What is the OOP way of doing this?
__________________
Jim

Last edited by jamesharte; 09-02-2004 at 04:19 PM. Reason: Minor correction to code
Reply With Quote
  #2  
Old 09-02-2004, 05:14 PM
MKoslof's Avatar
MKoslofAccessing Controls on one Form from another Form MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

Reference the other form as ByRef in your caller sub, then pass to the text box control or whatever control you need the value in question:

Code:
Public sub callForm(ByRef f as form1) f.TextBox1.Text = "some value" End Sub
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #3  
Old 09-02-2004, 05:48 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

You mean like the Module1 code in my first post?

Oh dear, I think we may be getting off on the wrong foot again.

Your suggestion will work if your code was in a Module called from Form1
But if Form2 was running totally independently how could you cause a button press on Form2 to write to a textbox on Form1?
I gave the extensive detail on my first post in the hope of making my dilemma clear.

Hey, it’s after midnight here in sunny UK and I have an early start in the morning. I’m off again for the weekend – part business part pleasure. Look forward to continuing this on Monday. Thanks for the prompt reply though.
__________________
Jim
Reply With Quote
  #4  
Old 09-03-2004, 06:33 AM
MKoslof's Avatar
MKoslofAccessing Controls on one Form from another Form MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

No.

Basically a form is just another object in .Net.

If you don't want to define it ByRef to your class which you can do, (where are you confused about that?) Just create a new instance of your form wherever you need it. And you don't need a module called form1..I have no idea what you are talking about here

This is from your code:

Code:
Module Module1 Public Sub DoSomething(ByRef f As Form1) 'Write to Form1.TextBox1 f.TextBox1.Text = "Hi From the Module" End Sub End Module

So now here is your question:

[/quote]
The question is. How do I write to Form1.TextBox1 FROM a button press on Form2?
[quote]

So you want to write text to Form1.TextBox1 From a button on Form2...how this not correct:

Code:
'in the button click event of Form2 'me is sending a reference of Form2 to the sub If TextBox1.Text <> "" Then Call DoSomething(Me) 'in the DoSomething sub Public Sub DoSomething(ByRef f As Form2) 'reference Form1 in your code Dim myForm as Form1 myForm = New Form1 'now passed the value from Form2 myForm.TextBox1.Text = f.TextBox2.Text 'show form1 myForm.showDialog
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #5  
Old 09-06-2004, 02:37 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

Hello again MKoslof, I hope you have had a good Labour Day Holiday.

Sorry, but, to use your terminology, “we are not on the same page!”

I have pasted your code into mine and sure enough it works – I could see that it would – by starting a NEW instance of Form1. But I don’t want to do that. I already have an instance of Form1 running and want to write to Form1.TextBox1 on that existing instance of the form!

You ask
Quote:
If you don't want to define it ByRef to your class which you can do, (where are you confused about that?) Just create a new instance of your form wherever you need it. And you don't need a module called form1..I have no idea what you are talking about here
I obviously did not explain myself clearly enough in my first post, or, dare I suggest it, you did not read it carefully enough

I have been crawling up the learning curve of VB.Net and discovered the code that I illustrated in the first post as

Code:
Private Shared m_vb6FormDefInstance As Form1
     Private Shared m_InitializingDefInstance As Boolean

     Public Shared Property DefInstance() As Form1
          Get
               If m_vb6FormDefInstance Is Nothing _
                   OrElse m_vb6FormDefInstance.IsDisposed Then
                    m_InitializingDefInstance = True
                    m_vb6FormDefInstance = New Form1

Etc. Etc.
which if added to the code of every form created can make the form available from anywhere in the code – just like in VB6 or Access Basic.

I also realise that I can pass values using Public variables. But these two methods fly in the face of good OOP if I am to believe what I have read during extensive searches of this Forum.

So researching further I came across a walk through which demonstrated a couple of techniques of writing from one form to another. The code I presented in my first post was nothing more than a trivial demonstration of what I had learned. – Module1 was only a trivial way of showing understanding of passing a form ByRef – so no I am not confused about that.

In my actual project the code in Module1 (or any other module) is much more significant. Indeed you have assisted in part by kindly providing some code to modify a DataGrid.

What I am talking about is that in my example, once Form2 has been opened by pressing Button1 on Form1, and whilst Form1 is still running, how can I write to TextBox1 on Form1 by pressing a button on Form2?

The example in my original post is trivial, but in my actual project, Form1 is a form for entering contact information. Form2 is a form opened from Form1 that allows the user to edit a subset of the information required on Form1. So when Form2 is complete, the result(s) is(are) passed to Form1. Form1 never closes so opening another instance of Form1 is not productive.

Please let me know if this is still not clear. A further perusal of my original post may be worth while.
__________________
Jim
Reply With Quote
  #6  
Old 09-06-2004, 03:31 PM
MKoslof's Avatar
MKoslofAccessing Controls on one Form from another Form MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

OK...here is an example..please tell me how we need to tweak this if not correct.

In design view I have two forms..form1 and form2. On form1 I have a command button and on both forms I have a text box.

In a module I create a public property:

Code:
Public Module globals Private m_Form2 As Form2 Public Property Form2() As Form2 Get If m_Form2 Is Nothing Then m_Form2 = New Form2 m_Form2.Show() Else m_Form2.Show() End If Return m_Form2 End Get Set(ByVal Value As Form2) m_Form2 = Value End Set End Property End Module

Now, I run my application. By Default Form1 is my main form. This loads with a blank text box..this is the only form present at this time. Now I put text in this text box that I want to send to the other form..again, currently no other instance of Form2 is loaded. I change the text box and click the command button:

Code:
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click globals.Form2.TextBox1.Text = Me.TextBox1.Text End Sub

So no instance of Form2 is present...a new form2 instance pops up on the screen with the value of form1.textbox1 in its text box. Now I have two forms open at once. Since I am using .show and not .showDialog, I can browse between dialogs. Now, if I change the text in form1's text box and hit the command button again..the text in the text box of Form2 changes but there is not another form2 instance..it is using the current Form2 instance and just changing the text box value.
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #7  
Old 09-06-2004, 03:55 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

Lets try and simplify this a bit more.

1. I have two forms. Form1 and Form2.
2. On each form there is one textbox and one button.
3. Form1 is the Main Form. When it opens there is nothing in the text box.
4. Pressing the button opens Form2 as a model form. I do not close Form1
5. I now type something in the text box on Form2
6. I press the button on Form2.
7. This puts the contents of the Form2 textbox into the Form1 textbox and then closes Form2.

At least that is what it would do if I could figure out how to implement line 7.
__________________
Jim
Reply With Quote
  #8  
Old 09-06-2004, 05:12 PM
MKoslof's Avatar
MKoslofAccessing Controls on one Form from another Form MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

OK, create a module, and on the startup of your application, set the first action to be the Module Main..so when the application loads form1 is displayed.

Code:
Module Module2 Private NewForm1 As New Form1 Private NewForm2 As New Form2 Sub Main() NewForm1.ShowDialog() End Sub Sub ShowForm2() If NewForm2 Is Nothing Then NewForm2 = New Form2 Else NewForm2.Show() End If End Sub Public Property TextFromTextBox1Form1() As String Get Return NewForm2.TextBox1.Text() End Get Set(ByVal Value As String) NewForm2.TextBox1.Text = Value End Set End Property Sub ReturnToForm(ByVal s As String) NewForm2.Close() NewForm1.TextBox1.Text = s End Sub End Module

Now, when the application loads Form1 is presented automatically. In the code in its command button (this opens up form2) use this:

Code:
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click ShowForm2() End Sub

Then in the code where you click the command button in form2 use this:

Code:
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Dim s As String = Module2.TextFromTextBox1Form1() ReturnToForm(s) End Sub

Now Form2 is unloaded and only form1 remains with the text from Form2 sent.
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #9  
Old 09-07-2004, 10:59 AM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

Wow! Great! We’re on the same page.

OK I started a new project and followed your guide and air punching was in order.
But my elation was short lived. Oh dear!

Form1 loaded as expected.
Form2 showed up after pressing the button on Form1
Typed text into Textbox on Form2
Pressed button on Form2
Form2 closed. Text appeared as expected on Form1

GREAT!

Pressed button on Form1 again and it threw an error as follows: Great sorrow!!

Quote:
An unhandled exception of type 'System.ObjectDisposedException' occurred in system.windows.forms.dll

Additional information: Cannot access a disposed object named "Form2".
Code:
Sub ShowForm2()
          If NewForm2 Is Nothing Then
               NewForm2 = New Form2
          Else
               NewForm2.Show()  ‘ ERROR HERE
          End If
     End Sub
Of course you might expect this to happen.

I am sorry MKoslof to put you through this, but I am in an area that I am still struggling to understand. I think that I understand what your code is doing. But I need to be able to access Form2 more than once and perhaps repeatedly.

I have more questions about this but one thing at a time.
__________________
Jim
Reply With Quote
  #10  
Old 09-07-2004, 12:47 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

Since the last post I realise that I can use

Code:
NewForm2.Hide()
__________________
Jim

Last edited by jamesharte; 09-07-2004 at 02:33 PM.
Reply With Quote
  #11  
Old 09-07-2004, 04:09 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

AS you might imagine the two-form example is merely a demonstration. In my project the two forms concerned are more complex and they are opened in an MDI Container.

Well Form1 is opened in an MDI Container, Form2 is opened as a modal form.

I have played with the two-form example and added a third form, Form3, as the MDI Container. I appear to be able to get everything working inside the MDI Container except that the text in the textbox on Form2 is not returned to Form1.

I’m at a loss again.

Do you need to see my code?
__________________
Jim
Reply With Quote
  #12  
Old 09-07-2004, 06:26 PM
MKoslof's Avatar
MKoslofAccessing Controls on one Form from another Form MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

OK, work has been hectic today..I could not get to the board. Well, the problem is, the dispose event is fired each time you close out the form instance. So you have a few options

1) Override the dispose event...this is tricky and sometimes dangerous
2) Check the default object and see if it is equal to nothing..if so, you need to create a new instance

3) Or, use the power of .Net try/catch error handler to simply catch the error and define your own new instance..see below, a slight modification of the original module code that will work for you:

Code:
Module Module2 Private NewForm1 As New Form1 Private NewForm2 As New Form2 Sub Main() NewForm1.ShowDialog() End Sub Sub ShowForm2() If NewForm2 Is Nothing Then NewForm2 = New Form2 Else Try NewForm2.Show() Catch ex As Exception 'the object was disposed NewForm2 = New Form2 NewForm2.Show() End Try End If End Sub Public Property TextFromTextBox1Form1() As String Get Return NewForm2.TextBox1.Text() End Get Set(ByVal Value As String) NewForm2.TextBox1.Text = Value End Set End Property Sub ReturnToForm(ByVal s As String) NewForm2.Close() NewForm1.TextBox1.Text = s End Sub End Module
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #13  
Old 09-09-2004, 02:16 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

So far so good.

Your code works as always – Thank you.

I am attempting to understand why and believe that I am getting there. I may have other questions about this later

But I must return to two questions raised earlier.

1
What (if anything) is wrong with using the “DefInstance” technique referred to in my original post? This makes every form accessible from anywhere.

2
In my actual project, Form1 is opened in an MDI Container; Form2 is opened as a modal form.

That is
Using Module2 I open Form3 as a MDI Container.
In the load event of Form3 I load Form1.

I have attempted to modify your code to allow Form1 and Form2 to behave as we have established in your last post.

But I can’t get the text in the textbox of Form2 to be displayed in the text box of Form1 as it did before using the MDI Container.

The problem manifests itself in the code below, but I suspect the source is elsewhere.
I have put two debug lines in to check things out. The results are shown in the code


Code:
     Sub ReturnToForm(ByVal s As String)

          Debug.WriteLine(s)      ' = the sting from the Form2 TextBox
          Debug.WriteLine(NewForm1.Text)     ' = "Form1"
          NewForm1.TextBox1.Text = s           'NOTHING SHOWS IN Form1  TextBox1
          NewForm2.Close()

     End Sub
This is obviously because I don’t clearly understand how all of your code works.
__________________
Jim

Last edited by jamesharte; 09-09-2004 at 03:11 PM. Reason: added some code
Reply With Quote
  #14  
Old 09-10-2004, 06:39 AM
MKoslof's Avatar
MKoslofAccessing Controls on one Form from another Form MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

Quote:
1What (if anything) is wrong with using the “DefInstance” technique referred to in my original post? This makes every form accessible from anywhere.
This is simply the VB.Net compiler making sense of your old VB 6 code. Form objects and instances have completely changed in .Net. DefInstance basically means "use the default Form1 object" within your code. If you leave this code within your project it should work. But again, you are still at the mercy of disposal events and garbage collection. A disposed form will always need a new instance. There is nothing wrong with using it...but if you want to use other methods you need to code them.

2) Is NewForm accurately being assigned to the current instance of Form1? Just because the NewForm object is a form object and referencing the proper text box does not mean it is referncing the default instance of Form1 that currently exists. If NewForm1 being declared as a new instance of Form1 within your startup main module. And if you have an MDI container, have you attempted to create a new private instance of this container object?
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
  #15  
Old 09-10-2004, 03:24 PM
jamesharte jamesharte is offline
Regular
 
Join Date: Jul 2004
Location: Yorkshire England
Posts: 83
Default

Thanks MKoslof for that last post. I was disappointed initially that you did not say “show me your code and I’ll show you your error.” But not having the solution given to me, I had to search for it.

In fact I had instantiated Form1 in the opening Module2 that opened Form3, then instantiated it again in the Form3 load event. So on the return from Form2 the string was applied to the wrong (not shown) instance of Form1.

This does raise a point though. This has been a long thread. That contains a lot of information. I am still not certain how some of the code works or what the processes are called. The semantics of the .Net language can be as confusing as the code for a novice (I can’t stand the word “newbie” or its variants). It would be helpful if when code was proposed it was annotated to say such things as “This is Overloading” or, “this is Inheriting from XXXX” or, “This is setting up a Class.” Am I asking too much?

For instance,

Code:
Sub ShowForm2() 
        If NewForm2 Is Nothing Then
            NewForm2 = New Form2
        Else
            Try
                NewForm2.Show()
            Catch ex As Exception
                'the object was disposed
                NewForm2 = New Form2
                NewForm2.Show()
            End Try

        End If
    End Sub
I really find parts of this confusing. (Don’t explain, I will ask again another time if I don’t eventually get it – I think I am already close!)

So I think this brings this thread to an end – phew!

Many thanks for your continued patience – I’ll be back to haunt you again - soon.
__________________
Jim
Reply With Quote
  #16  
Old 09-10-2004, 06:04 PM
MKoslof's Avatar
MKoslofAccessing Controls on one Form from another Form MKoslof is offline
Cum Grano Salis

Retired Moderator
* Guru *
 
Join Date: Jul 2002
Location: Baltimore, Maryland
Posts: 14,636
Default

OK, I don't mind long threads..it keeps me up on my toes . Let us know if you have more questions..we are always here to help the best we can. Good luck.
__________________
"Artificial Intelligence is no match for natural stupidity." ~unknown
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
 
Accessing Controls on one Form from another Form
Accessing Controls on one Form from another Form
 
-->