• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 411
  • Last Modified:

VB.Net Updating textbox from different class with mdi app

Hi Experts.  I have an MDI application where each instance of a child form accesses a sub in a different class  The class should then update the textbox on the child form that requested the update.   This is not happening and I understand that this is because the sub is updating the textbox on the original version of the form and not the current child version of the form. I have found a few solutions to this on the web but am struggling to understand any of them.  Anyone got a simple solution I could try?  Also, in a way that would ensure that the update is carried out on the one child form that requested the update and not all of the currently opened child forms.  Many Thanks in advnace
0
PNRT
Asked:
PNRT
  • 11
  • 8
  • 7
1 Solution
 
AndyAinscowFreelance programmer / ConsultantCommented:
You need to pass the function an instance of the textbox on the form you want updating.  Something like this (I usually use C# so it might need slight modification):

sub Foo(ref txtBox as Textbox)
  txtBox.Text = "hello"
end sub

and you call it like this
Foo me.txtBoxToBeUpdated
0
 
PNRTAuthor Commented:
Many Thanks for the reply.  Sorry not following this.   Is Foo in the form and the call in the separate class?  Not sure how this would ensure the correct form.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
Foo is the function in the class common to multiple forms you want to call.

>>Not sure how this would ensure the correct form.
Because you are calling it from the form the textbox is on and passing the instance of that specific textbox:
Foo me.txtBoxToBeUpdated
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
PNRTAuthor Commented:
I think I must have not explained myself properly.     The class is running continuously and needs to update the textbox with different values at certain times.   The update process is fired by what is happening in the class and not from the form.   Would I then call it from the class?   Thanks again for the reply
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
>>The class is running continuously
Not certain what you mean by that.  

Maybe you want to store a reference to the form when you start the process (= class ??) and then it can use that to update when required.
0
 
PNRTAuthor Commented:
>>The class is running continuously
 Not certain what you mean by that.
I meant that it is doing stuff all the time, monitoring a folder and updating the textbox as changes occur
Referencing the form at the start sounds more like it.  Can you advise how the format would go?
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
Just pass the form (me) in as a reference and keep it as a class level variable.  Something like:

sub Foo(ref frm as Form)
  classLevelFrmVariable = frm
end sub

and you call it like this
Foo me
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
Many factors can influence what you are doing.

Are all the children instances of the same form, or are there some children that display a different type of form.

How do you create your children? Old tricks from VB6 such as using a Form without explicitly instantiating it (calling New) limit you in .NET, because you lose control.

How do you call the method in you class? Are you using My? My is an easy way to deal with forms, but you lose a lot of possibilities when using it, even more so in an MDI environment where you have many instances of a form. My sees only the first one.

Could you post the class method AND the code that you use to call it. We could then understand how you are communicating between the form and the class, and then tell you what your approach is.
0
 
PNRTAuthor Commented:
Thank you Jacques  
This is the code instantiating the form

Dim frm2 As New Form2
frm2.MdiParent = Me
frm2.Show()

frm2 then creates a TcpListener on a new thread accepting socket connections from a sub in the class

While True
     Dim user As New ConClient(listener.AcceptTcpClient)
End While

The class monitors the connection status and then send the connection status to the textbox on frm2

I have tried

Form2.TextBox1.AppendText("Connection status >" & strStatus)

But I understand that this is trying to update the original form and not the various frm2's

Hope this helps
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
If you look at my initial posting you need a reference to an instance of a form or textbox on a form.
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
Form2.TextBox1.AppendText("Connection status >" & strStatus)

That an old trick from VB6 that can cause problems in .NET. A form is a class. When you create a form in a designer and give it a name, you are creating a class. That is why you can instantiate a New Form2. But in the background, .NET creates a variable called Form2. The first time that you use it, it is automatically instantiated for you, with the following code, that you do not see because it is generated only by the compiler:

          Public Form2 As New Form2.

Thus, when you are calling Form2.TextBox1, you are using that variable instead of the one you created yourself.

If you do not what to have problems when working with forms, never call then by their name. Always call them by the variable that you create when you instantiate them, or by using one of the following tricks when you have multiple copies of the same form. Take the good habit of doing it even when you have only copy of the form.

In your scenario, it would be hard to know if you need to call frm1.TextBox1 or frm2.TextBox1, so let's do it another way.
The way to call you method depends on where you code is.

If the code is in Form2, then do the following. Me is the instance, that is the form that is running the code:

          Me.TextBox1.AppendText("Connection status >" & strStatus)

If that code is in the MDI parent, then you will have to do the following. The DirectCast tells the compiler that the current child is a Form2, so that TextBox1 will be recognized as a valid property of the child:

          DirectCast(Me.ActiveMdiChild,Form2).TextBox1.AppendText("Connection status >" & strStatus)
0
 
PNRTAuthor Commented:
Thank you Jacques.  I'm getting much more of an understanding.  
The updating code though is not in either form it is in the separate class that frm2 calls and that
monitors the connection status.
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
Do you have only one instance of your class running, or do you create a new object on the class for each form?
0
 
PNRTAuthor Commented:
I have only one instance of the class running and suspect that I will have to address that problem  by recreating the class for each form.   I was hoping to try and solve this issue as the only thing not work, before moving on.
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
OK, a little further.

Is the class in the same project or is it in a dll?

Do you instantiate the object on the class from the MDI or do you instantiate it from somewhere else? If so, from where?

Now, when you need to update the form.

Do you need to do it for all the forms, or only for specific forms. If it is for specific forms, how do you identify the forms that need to be updated?

Sorry for all these questions, but when you want 2 objects to communicate with each other, you need to know the available paths between them.
0
 
PNRTAuthor Commented:
Sorry its so slow.

The class is in the same project - classname.vb

I create multiple identical childforms in the mdi app and then each of the childforms refers to the class
But each of the childforms has slightly different parameters such as a path

All of the childforms are identical and each must communicate with the class and each must receive updates back
to each of their textboxes.

As I said, I think I may have to have multiple classes for multiple childforms.  Still have to solve that, still trying to get one to work :-)
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
each of the childforms refers to the class. How? Does it need so set specific properties? Does it call specific methods?

But each of the childforms has slightly different parameters such as a path. Are these parameters used in only one place in your class, or are they used in many different places.
0
 
PNRTAuthor Commented:
This is the code in the childform

While True
      Dim connecteduser As New ConClient(listener.AcceptTcpClient)
 End While

The parameters are used only once when the class is intitiated   - the ip and the port that it must listen on
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
Is there something missing there? I see an infinite loop that creates a new instance of your class in each loop. I do not get that one as you show it. How many objects do you create in memory. Doesn't that thing bomb after a while?

But lets go anyway.

If each child calls New ConClient and thus has its own instance, then the solution is simple

I such a situation, the solution is really simple.

Change the constructor in your class to the following:

     Private _parent as Form2
     Public Sub New (<the already defined parameter>, parent As Form2)
         <The code you already have in your constructor>
         _parent=parent
     End Sub

This will enable you to pass the form that is using that specific instance when you create your object:

      Dim connecteduser As New ConClient(listener.AcceptTcpClient, Me)

This way, you are passing your form to the class, that records it in its _parent member.

When you are ready to update the TextBox, call it through that reference:

      _parent.TextBox1.AppendText("Connection status >" & strStatus)
0
 
PNRTAuthor Commented:
Thank you I'm putting it together to test now.
Just one thing more.  If the each childform calls the class, is each childform creating a different instance of the class or in fact will each childform be trying to use the same instance - which is obviously is not going to work
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
Every time you call New on a class, you create a new instance. That means that if you call New in each form, each one has a different instance (unless you use Shared methods and properties in your class. If you do not know what Shared is, no problem, it means that you did not use it).

So you should be OK to go.

Your original problem was that Form2, that referred to the default form created by the VB compiler (stupid idea if you think like me... just to save a variable declaration). With the method I sent you, each instance knows which form called it, it is recorded in it's _parent variable (which, by the way, might be better called _parentForm).

Unless there is something hidden from me however, the place where you are not OK is that loop. Why do you instantiate your ConClient in a loop? Isn't one instance sufficient for each class?

I have to go for a while. I might be able to get back in an hour or so, otherwise it will probably be only at the end of the evening (Montreal / Eastern Time). The Montreal Canadiens will crush Tampa Bay again tonight, and I would not be a real Québécois if I was to miss that game.
0
 
PNRTAuthor Commented:
Thank you so much for your patience.  Its working and just as importantly I understand it
Enjoy the game
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
You also showed a lot of patience.

Patience and explaining stuff is my work. For me, it is a lot easier to do that live in front of a training room filled with French programmers, so I am glad when I see that I can also do it in English and far from the programmer I am "talking" with.

And Montreal won the game, so I am glad twice.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
Now you understand - go and have another look at what I said and it should be clear what I was attempting to show you.
0
 
PNRTAuthor Commented:
I see that Andy, thank you.  The explanation was just a bit over my head.  Jacques had to go to basics to get it across.
2 - 1 was close though - Canadiens rule?
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
I don't like writing essays, never have done.   ;-)


>>Canadiens rule?
Well tonight they play Switzerland (Ice hockey) - wait and see.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 11
  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now