I've got a Windows Forms .NEt application that uses 2 forms.
I've got Form2 which is created from Form1 :
(inside a Form1 button click event handler) :
namespace::Form2 *myForm2 = new namespace::Form2;
myForm2->Show();
This Form2 works well, & I now have the need to write text to it's textBox1.
So I create one in Form2[Design]. I need to do this textbox population inside a function X that is defined within namespace but outside the definition of Form2. Function X is called from another button click event handler of Form2.
How should I do this
I've tried :
(inside the function X definition) :
namespace::Form2::textBox1->set_Text(blah blah blah);
but I get error C2227 : left of '->' must point to class/struct/union.
I've also tried including a pointer to Form2 in the function X definition :
namespace tester
{
BOOL X(Form2* pForm2, ...)
{
pForm2->textBox1->set_Text("hi");
}
}
...
private: System::Void button2_Click(System::Object * sender, System::EventArgs * e)
{
dStatus = tester::X(this, var1, var2);
}
It tells me that Form2 is undeclared identifier - this error occurs in the function prototype statement
I can't seem to shake this error - any advice Why is textBox1 is not seen as a class Under Class View - I see it displayed just as other textBoxs of Form1.
The only difference is that the Form2 buttons have click event handlers associated with them, while the textBox is populated with a strng inside one of these button click event handlers.
(Perhaps there was a better way to create Form2 from Form1 )
ak

using a textbox from a 2nd Windows form
GrayShade
I guess a simpler version of my question is this :
Suppose I have a Form1 that, upon clicking it's button, launches a new Form 2.
There's a textbox in Form2, which must be populated with a string where :
a) the population occurs inside a function seperate from any Windows Forms
b) the value of this string comes from a variable that is an argument to this function
How would you do this
Alan Caceres
Think of your Windows.Form derivitive class as two things:
1. a dialog box with controls (and if you can't bring the first form to the front while the second form is top of it, then the second dialog is "modal") Keep the controls private. Make them private now... stop trying to use them from the first form. :)
2. a class that contains properties that are pertinent to the operation of that form: some are inputs, some are outputs, and some are both. Some of these properties are going to be public, to be exposed to whatever created the form, and some are private, for the internal bookkeeping of the form.
This distinction is important.
If the second form MUST have some meaningful value that has no default that you can assume, then my suggestion is to pass that value into the second form's constructor, because it forces data flow. (You are not obliged to have a zero-argument constructor). Have the second form set the relevant private property in the body of its constructor.
If you don't choose to use a contructor, use at least put in a property in the second form that the first form can pass information to. Again, do NOT have the outside world talking to the second form's controls. Those are the second form's "private parts." Earlier, we said you shouldn't do it, but it's easier now to tell you not to do it. :)
The data exchange between the first form and the second form happens while the second form is not showing. You instantiate the second form, passing it values either via its contructor or its properties. Show the second form, let it party, and when the second form closes (i.e. Show() returns), the first form retrieves information via the second form's properties.
When does the data flow happen from the form's properties to the controls themselves Typically this would be done in the handler for the Load event. Use the FormClosed event to do data flow in the opposite direction when the form closes.
So again, the data flow for a particular piece of data (e.g. your string) is:
First form -> Second form's public properties before Show -> Second' form's private controls during the Load event handler -> user interaction with the controls -> Second form's public properties during FormClosed event handler -> First form reads a property belonging to Second form.
If you don't know what a "property" is, you should go to MSDN and read up.
Brian
Chris Patten
Same pattern! The class containing Function X (Call it MyClass::X()) needs to have access to an instance of Form2, not the class itself. Let Form2 have a definition of an event that is public. Let MyClass define an event handler, whose delegate is added to Form2's event via +=. Then let Form2 fire the event upon the click of the button you mention.
But if MyClass has no access to Form2, then maybe you should be thinking about the overall architecture of your application. From reading this thread and your attempts to "just get it to compile" restructuring looks to be in order.
Brian
fragglefeet
My string gets defined as an output from an earlier function that is called within a button click event handler of Form2.
Then, a second button of Form2 is clicked : function X is called & within this function I would like to place the command to populate the Form2 textbox with my string. technically, I could place this command within the button click event handler of Form2 & that would make things simpler to compile, but I would really like to place this statement within function X itself (specifically, within a for loop in function X, that cycles thru the index of my variable of interest, & which upon converting to a string, would be displayed in textBox1). So I don't see why I would need to get pass any information between Forms 1 & 2 - they're 2 seperately operating forms.
I hope this makes sense.
ak
Soren Lund
I'm assuming that "Function X" belongs to Form1, right. If so, refer it as Form1.X(): it will alleviate confusion. (Or Form1::X() if you prefer.)
If your Form2 is modeless, then think of the whole thing as a control of Form1. In particular, think of Form 2 firing events (like controls do) and Form 1 handing them.
You've seen this going on already in your WinForm implementation, except it was automatically added by the designer. Now create your own event that is fired from Form2 in particular, within the button Click handler. Form2 is to have an implementation of a handler for this event. You'll add its delegate to the event itself (belonging to Form2), using +=. The pattern is already there (between controls of a form and the form itself), and you can use it to communicate between forms.
But if I'm wrong and that "Function X" is implemented by Form2, the same pattern applies.
Does this get us closer
Brian
ravi bhagat
I guess one way to resolve this issue is to just dump the body of function X into the Form2 button click event handler & eliminate X altogether.
ak
ScottK11203
:: is a namespace and class scoping operator. instance->method() is what you need to invoke a method on an instance of a class. You need an instance of a form, which has an instance of a textbox:
With:
Form2^ myform2 = gcnew Form2().
Form2 is the class. myform2 is an instance of class Form2. If you look at the implementation file of Form2, you will find somewhere TextBox^ textbox1 = gcnew Textbox(), but with Textbox itself fully qualified with the containing namespace, using the scoping operator :: textbox1 is an instance of the class TextBox.
Instead of pseudocode that is partially right and likely to further confusion, read the real code you already have: it's your Form2 implementation, mostly maintained by the Visual Studio designer. For your delegate example: Study Form2: find where you have an +=. This is an example of a event (belonging to a control) that is associated with a handler/delegate.
Brian
Brian
Jon Asbury
can't work because because you are not operating on any instance of Form2 here. (The only way the above makes sense is if it were textBox1 were declared static... don't do this though!)
You do have a form instance. It's created from:
namespace::Form2 *myForm2 = new namespace::Form2;
You can then do:
myForm2->textBox1->set_Text( mytextvalue );
Before you call:
myForm2->Show();
It's not a very clean practice to access a form's controls externally this way. But it might be better to pass the text to Form2's constructor (i.e. make it part of the data flow between form1 and form2), and let Form2 populate the text box in its Load handler.
e.g.
namespace::Form2 *myForm2 = new namespace::Form2( mytextvalue );
While this seemed like a "C++ language" issue, it really isn't. If your question pertains more to Winforms than C++, you should post your question in the Windows Form General newsgroup.
Brian
Theo Postma
Maybe you can give me a pseudocode example - I'm new to delegates and such & it's difficult for me to follow your explaination.
If I don't declare an instance & use :
namespace::Form2::textbox1->set_Text("hi");
I get C2227 : left of ->set_Text must point to a class/struct/union.
daveashmore
nhlpens66
1) the text to be placed in the textbox is not a fixed string but instead gets its contents from a variable within the function X that the statement :
myForm2->textBox1->set_Text( mytextvalue );
resides in. This makes it automatically executed after the myForm2->Show statement (which is part of the parent form).
2) I can successfully operate with buttons of Form2 & probably anything else that involves creating a event handler from within Form2. Unfortunately, this set_text command is within a function.
I'll paste this reply into the Windows Forms General forum.
Regards,
ak