I'm new to C# and trying to figure out how to edit a form from another class. The form is created by the default VS approach, as so:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
I've created a method in the Form1.cs file, just as a test for how to update a label1 field that is in Form1. Here is the method:
public void UpdateLabel(string state = "Changed Text")
{
label1.Text = state;
}
The problem I'm having is that the Application.Run command doesn't provide for a named object of type Form1. So when I want to trigger the UpdateLabel method from Program.cs, like so:
XXX.UpdateLabel();
I don't have an object to target to access the form. If I were creating the form manually, then I believe this would work fine:
Form1 myForm = new Form1();
myForm.UpdateLabel();
With the Application.Run(Form1) that the Windows Form Application provides, how do I access the form object that is being created? Also, is this the approach I should be taking for this type of problem, or is there a better method?
Well, you could integrate your last example in this way....
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 myForm = new Form1();
myForm.UpdateLabel();
Application.Run(myForm);
}
but let me ask you: Why your logic dictates to do this outside the Form1 constructor?
public Form1()
{
InitializeComponents();
label1.Text = "Changed Text";
}
EDIT: Following the comments below I think you should work on something like this:
MyApplicationCode appCode;
public Form1()
{
InitializeComponents();
appCode = new MyApplicationCode();
this.Text = appCode.GetFormText();
label1.Text = appCode.GetLabelText();
cmdSave.Enabled = appCode.UserHasSavePermission();
...... // and so on for other decisions on
}
You could fix the immediate issue with:
Form1 form = new Form1());
form.UpdateLabel();
Application.Run(form);
As for the second question, it really depends on what you are trying to ultimately achieve.
So you have some fairly complicated logic that is used to determine the initial value of some controls in your form. Due to the complexity of that logic, you would prefer to extract that code from the definition of Form1 and move it to another class. That is all good so far.
You can create some other class, have Form1 use that class, and have it provide a value to Form1. Rather than having some other class that has-a Form1 (which would be the effect of putting your code in Main, Form1 should have that other class.
Implementing this is fairly simple. You create another class, you give it an instance or static method that returns a string. Form1 either calls the static method, or creates an instance of the class and calls the instance method. It then sets a label based on the results of that method.
Application.Run is typically used to launch a WinForms application until such a point that that application closes. What function of your Program.cs class is supposed to call UpdateLabel? Is your application launched externally with label value parameters?
Related
So I have the template C# windows form, and made the debugInstructionsLabel label public so that I can edit it from outside the form, then added a few lines to main:
namespace test {
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 form = new Form1();
Application.Run(form);
form.debugInstructionsLabel.Text += "Aaaaaaa";
form.Refresh();
form.Update();
form.Invalidate();
Application.DoEvents();
}
}
}
However, this doesn't actually change anything in the form, how would I update the text?
EDIT: It seems like Application.Run doesn't return, should I create another thread or handle everything inside the form class?
You should put the line that changes the text of the label in the onLoad event of the form. Even on the constructor after initializecomponents is run would be fine. With that minor change it will work.
Hope this helps!
I have simple Form1.cs which includes buttons, text boxes, etc.
I would like to bulid a new class and to have the ability to call buttons and test boxes from Form1.cs
In the new class, when i type for example textbox. nothing appears.
What is the easiest way to do this?
Thank you
You can pass the Form1 instance to the new class. The easiest way is to assign it at initialization. If you create the new class instance while in Form1, then use this:
In Form1:
NewClass nc= new NewClass(this);
With the new class looks like this:
public class NewClass
{
Form1 fm;
public NewClass(Form1 frm)
{
fm=frm;
}
void ChangeTextBox()
{
fm.YourTextBox.Text="Foo";
}
}
You should try
Form1.textbox
or
Form frm = new Form1();
frm.TextboxName
Where as to get the values of one form to another form you can also send it via objects. If you create the class of the values you are taking. and assign the values to the class members.
You need to take several steps for this.
First of all, you need to expose the controls you want to access outside the form. To do so, in designer, select each control -> right-click -> Properties -> Modifiers -> change selection to Public;
Afterwards, in your class, create an instance of Form1 and access the controls you need:
var form = new Form1();
form.TextboxName.Text = "some text";
create a new instance of the class \ form
var myForm = new Form2()
then use myForm then call the control from this such as
myForm.TextBox1.Text = "your text here"
I have a form, Form2 which contains a Hangman game (yes, it is the similar Hangman game to the one that i'm referring to in my previous question) and once the player finishes the game, the player will be brought to either one of two forms, Form4 and Form6 (one is a congratulations form for winning and one is a mocking/defeat form for losing) and in both forms Form4 and Form6, there is a label that displays the score that the player gets from the previous Form2.
I had placed a method to return the value of the score in Form2.
public int getScore()
{
return score;
}
And then in both forms, Form4 and Form6, there is these codes in each form respectively.
Form4
private void Form4_Load(object sender, EventArgs e)
{
Form2 game = new Form2();
lblFinalScore.Text += game.getScore().ToString();
}
Form6
private void Form6_Load(object sender, EventArgs e)
{
Form2 game = new Form2();
lblFinalScore.Text += game.getScore().ToString();
}
So after passing Form2 and playing the game, and when for example, I won the game and got 7 points, and Form4 appears, the lblFinalScore displays 0... WHY?!
Please help...
If you use the new keyword you create a new instance of the Form2 class.
This way you are using two different instances. Differnt instances are having data fields with different values.
If you want to access the same data field from any intances of a class, use the static keyword. You could store the score value in a static field, this way you could easily access it.
If you have a static field defined in a class, you can access the very field from any instance. However, using static fields are highly discouraged, since this violates basic OO principles.
Example:
class Program
{
static void Main(string[] args)
{
ExampleClass ex1 = new ExampleClass();
ExampleClass ex2 = new ExampleClass();
ex1.normalfield = "new value for ex1";
ex2.normalfield = "new value for ex2";
ExampleClass.staticfield = "static value";
Console.WriteLine(ex1.normalfield);
Console.WriteLine(ex2.normalfield);
Console.WriteLine(ExampleClass.staticfield);
}
class ExampleClass
{
public string normalfield = "";
public static string staticfield = "";
}
}
Passing the original instance of the Form could be a better way to go in your situation.
This could be done by storing a reference to the Form, or implementing the Singleton pattern.
However, the best solution in my opinion, would be to decouple the presentation of your game logic. You should be using a different class to implement the game logic and to store data values connected to the game and the form classes should be only responsible to present visually the current state of the object representing the state of your game.
You are creating two different instances of Form2. Refer to actual original instance of Form2.
Have class level variable on both Form4 and Form6 and set it from respective constructor. Pass instance from Form2.
Refer to Passing a value from one form to another.
I'm working on a term paper that performs operations with complex numbers. Application looks like this:
If you click on "Calculate", will calculate the operands and the result is displayed in a new dialog box. So I have two dialogs - a main window (up on pic) to display the read result (down on pic). Unfortunately I was not able to save result in the main dialog box, which is then written to a text file. There is important piece of code:
Thank you for ideas.
In your MainForm class declare a property as
public class MainForm:Form
{
public string CalculationResult { get; set; }
...
...
//Your code here
...
...
}
then on method of calculate change it to
if(resultBool!=null)
{
CalculationResult = resultBool.ToString());
formResult dlg=new formResult(CalculationResult);
dlg.Owner=this
dlg.StartPosition=FormStartPosition.CenterParent;
dlg.ShowDialog();
}
else
{
...
...
//your code
...
...
}
and change the following line
sw.WriteLine("Result: ");
to
sw.WriteLine("Result: " + CalculationResult);
in saveData method which is in MainForm class. Hope this will work for you. Happy coding
You have to use a reference on the target form to write on it.
You have to assure that you use the correct targetForm reference. You could either create a new targetForm or use an existing one. You could for example use the "parent" form of your dialog box and set the text of the main form textbox, from a dialog box event (using this as MSDN reference):
Dim targetForm As Form = Me.parentForm
targetForm.targetTextBox.Text = "text"
Hope I helped!
In formResult create a variable which keep a reference of Main form
private MyMainForm _mainForm;
Then create one more constructor which take reference of your Main form as parameter:
public formResult(MyMainForm mainform)
{
this.InitializeComponent();
this._mainForm = mainform;
//Now you have access to public property ResultOut
this.textBoxResult.Text = this._mainForm.ResultOut;
}
After this you can use all public properties and method of your main form in second form(formResult)
I am trying to have a click event on a new form that gets the text property of controls in form1.
I have made a public method that returns the values that I need but the returned values are always null. I have looked everywhere for this.
Form1:
public List<string> returner()
{
List<string> thevalues = new List<string>();
thevalues.Add(textbox1.Text);
thevalues.Add(textbox2.Text);
return thevalues;
}
Form2:
Form1 x = new Form1();
List<string> values = x.returner();
label1.Text = values[0];
label2.Text = values[1];
My issue is that there are no values returned because Im declaring a new instance of Form1 rather than using the one that has values in it (I guess).
Yes, that would explain what's going wrong. Basically you need to tell Form2 about the relevant instance of Form1. Exactly how you do that will depend on what constructs everything. For example, you might have:
Form1 form1 = new Form1();
Form2 form2 = new Form2();
form2.Form1 = form1;
Or you could pass the reference in the constructor to Form2.
If those are really the names of your forms, by the way, I'd strongly advise you to rename them to something more meaningful - something which indicates the purpose of the form. Likewise returner not only violates .NET naming conventions, it also doesn't explain what it's doing.
you've messed up with your codes.. if you want to get a value of text just use this. string textValue = form1.textbox1.Text
or.. since you didnt post the full code here.. try this rather than creating the object form1.returner();