C# .NET running code from an external file - c#

I'm pretty new with C#, and I was wondering if it would be possible to move parts of code (from my main Form) to an external .cs file (still in the same solution), with the same level of access to variables and functions from my form1.cs file, as my original form1.cs file.
I'm working with the latest version of the .NET-framework and I have no other references to (external) code.
Here is a simple example of what I'm looking for:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Code1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
// variables
text1 = "Hello"
public void ExternalCode()
{
this.BackgroundImage = null;
Btn1.Text = "Click me";
Lbl1.Text = text1;
}
private void Btn1_Click(object sender, EventArgs e)
{
ExternalCode();
}
}
}
This form only has a button named "Btn1" and a label named "Lbl1" in it.
I would like the code inside the method SeparateCode to be in a separate file, but still with the ability to access the variables and controls from Form3, and for Form3 to still be able to execute the method in the external file (ExternalCode).
I thought of making this file a daughter of the Form3.cs, but as I said, I'm still pretty new at this so I don't really know how to.

Yes, that is possible, because the class has been declared as partial, here:
v-----v
public partial class Form3 : Form
This keyword means that the file you grabbed that code from can be one of many, all declaring their own partial content for this class.
So what you can do is add yet another file to your project, and make sure it contributes to this class. To do that you must:
Declare the class inside the file as belonging to the same namespace as the original
Declare the class inside to be the same class as the original
Note that you don't have to mention inheritance, such as the part with : Form from your original, as this will still be understood from your original file.
So, if you add a file with this content:
namespace Code1 // <-- this has to be the same
{
public partial class Form3 // <-- as does this
{
public void ExternalCode()
{
this.BackgroundImage = null;
Btn1.Text = "Click me";
Lbl1.Text = text1;
}
}
}
then you can remove ExternalCode from your original file, and it should still work just fine.
The compiler will treat all of these files as building up the same, one, class, Form3.

Related

Run a certain command on app startup

I am trying to execute a certain string of commands on the start of a program, but it is not running. I have tried multiple things but my code right now looks something similar to this
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace scriptname
{
public partial class Form1 : Form
{
public List<string> stringName = new List<string>();
public int stringCount = 0;
public Form1()
{
InitializeComponent();
}
//this code needs to run on app startup.
//--------------------------------------------------------------------------
public Awake()//this is from my knowledge with Unity
{
if (!Directory.Exists(#"C:\Example"))
{
Directory.CreateDirectory(#"C:\Example");
StreamWriter exampleText = new StreamWriter(#"C:\Example\Example.txt");
}
else
ReadFromFile();
}
//--------------------------------------------------------------------------
}
}
Note, I am using visual studio forms as my base.
I am trying to get the highlighted text to run on startup, but every time I check, the folder isn't made. All I can think is that the code isn't running.
I really don't know how to initialize it on startup, and I was hoping for some help. I can make it run on a button press, but then where is the fun of that?
Awake is something that works with unity. Thats not going to work on a Forms app
public Form1()
{
InitializeComponent();
Awake(); // This will call awake when the form starts. Consider renaming it
}
public Form1() is the constructor of this form class. It will always be called when ever you load the form. Everytime you run this form that method will be called. If you only want the code to be run once regardless of how many instances of the form you create at run time you should move the code to the Main method in the default Program.cs.
You should also not save or create directories right in the C: drive. You should use the App data folder.
The best way is to use the proper events to trigger on the point in time you want. There is a event that are actually fairly close to what Unity has with it's Awake function. It is called OnLoad and is run whenever the Load event happens (which is right before the form is shown for the first time)
public partial class Form1 : Form
{
public List<string> stringName = new List<string>();
public int stringCount = 0;
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e); //You must remember to call base.OnLoad(e) when you override
if (!Directory.Exists(#"C:\Example"))
{
Directory.CreateDirectory(#"C:\Example");
StreamWriter exampleText = new StreamWriter(#"C:\Example\Example.txt");
}
else
ReadFromFile();
}
}

Control does not exist in current context

I'm sure this is something simple that I am just overlooking, but I can't figure it out. I am new to C# and I'm trying to create a calculator application. I have created my form with all of my buttons/textbox on it. Now I'm creating a new class to handle all of my methods and whatnot. My problem is that whenever I'm trying to reference controls on the form in the second class, I get the "does not exist in the current context" error. How can I solve this?
An example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public class Calculator
{
decimal currentValue = Decimal.Parse(displayValue.text);
}
}
displayValue receives the error. Thank you for any help.
The Controls can be called only from the .cs file which is linked with the form controls.
What you can do is create a parameterized constructor of your Calculator class like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public class Calculator
{
public Calculator(string displayValue)
{
decimal currentValue = Decimal.Parse(displayValue);
}
}
}
Now, you can call this class in the form .cs where you have buttons and textboxes like this:
Calculator calculate = new Calculator(displayValue.Text);
When you create a new Windows Form Application, there's a designer (which you can interact with to add your buttons and textboxes) and the code-behind (a .cs file).
This .cs file is a partial class, meaning it is also defined by the form you are interacting with. (you can see the nitty gritty details in your .Designer.cs file)
Once you name your buttons and textboxes, you can refer to their names in the code in your partial class!
And when you compile this, your button text will change to "Hello World!"
Hope this helps.
You will find this control in partial class of the form. You can take values from it and do your operation
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string s = textBox1.Text;
}
}

How to make a form visible or invisible in C# [duplicate]

This question already has answers here:
Why is there a default instance of every form in VB.Net but not in C#?
(2 answers)
c# Show Windows Form
(4 answers)
Closed 9 years ago.
So I have a Windows Form named Settings.CS
It has nothing.. the code is only this much
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SteamBot
{
public partial class Settings : Form
{
public Settings()
{
InitializeComponent();
}
}
}
Then I have another CLASS named Bot.CS. What I want to do is, after a specific function, I want the settings form to become visible. In VB it was just Settings.Visible = true
How do I do this in C#? Please help me.
Solution 1: if you want to display the Settings Form first time, you need to create an instance variable of that Form and call ShowDialog() method to display it.
Try This:
void SpecificFunction()
{
//--at the end of MyFunction call settings form
Settings frmSettings=new Settings();
frmSettings.ShowDialog();
}
Solution 2: if you want to display the Settings Form which was hidden before , you need to to follow the below steps make it Visible.
Step 1: identify/obtain the Settings Form by using Application.OpenForms[] Collection.
Step 2: create a new instance variable of a Form by casting the obtained Settings Form in above step.
Step 3: Call the Show() Method on the created instance variable to Show/Display the Settings form.
Try This:
void SpecificFunction()
{
//--at the end of MyFunction call settings form
Form frmSettings = (Settings) Application.OpenForms["Settings"];
frmSettings.Show();
}
Lets assume that Specific Function is a button click
private void Button1_Click(Object sender, EventArgs e )
{
Form1 myForm = new Form1();
myForm.Show();
}
Replace Form1 with the form name of your settings form !
I just created this new Form which is shown when the button is clicked:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form f2 = new Form();
f2.Visible = true;
//f2.Show(); also works
}
}
}
You can also use 'this' if you want to manipulate the instance
give it a try

An object reference is required for the non-static field, method, or property 'WindowsFormsApplication1.Form1.label1'

I want to reuse a piece of code, so I figured I'll make a class with a method that contains that code, and then I'll just call the method wherever I need it.
I've made a simple example of what my problem is:
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
LoadText.getText();
}
}
}
LoadText.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowsFormsApplication1
{
public class LoadText : Form1
{
public static void getText()
{
WindowsFormsApplication1.Form1.label1.Text = "New label1 text";
}
}
}
As you can see I've got one form with a label, and I want to use my other method (getText in LoadText) to change the text of the label.
Here's my error message:
An object reference is required for the non-static field, method, or property 'WindowsFormsApplication1.Form1.label1'**
I've already changed label1 from private to public under design.
How can I fix this problem?
The problem is that Form1 is a class, not an object. label1 is not a static member of the class, it is a member of the instance of Form1. Hence the error, which tells you that an object instance (of the Form1 class) is required.
Try the following:
Form1.cs:
LoadText.getText(label1);
LoadText.cs:
public static void getText(Label lbl)
{
lbl.Text = "New label1 text";
}
You now have a static method that will accept a Label object and set its text to "new label1 text".
See the following link for further information on the static modifier:
http://msdn.microsoft.com/en-us/library/98f28cdx.aspx
HTH
This is a common problem for newcomers to OO programming.
If you want to use a method of an object, you need to create an instance of it (using new). UNLESS, the method doesn't require the object itself, in which case it can (and should) be declared static.
I tried a different method that worked also:
Form1.cs:
// here a static method is created to assign text to the public Label
public static void textReplaceWith(String s, Label label)
{
label.Text = s;
}
LoadText.cs:
namespace WindowsFormsApplication1
{
public class LoadText : Form1
{
//new label declared as a static var
public static Label pLabel;
//this method runs when your form opens
public LoadTextForm()
{
pLabel = Label1; //assign your private label to the static one
}
//Any time getText() is used, the label text updates no matter where it's used
public static void getText()
{
Form1.textReplaceWith("New label1 text", pLabel); //Form1 method's used
}
}
}
This will allow you to use a public method to change the text variable for your label from just about anywhere. Hope this helps :)
You need a reference to your form in order to access its elements.

C# and Variable Scope in Winforms

Within a Winform app, I would like data in an instantiated class to be accessible by multiple form controls.
For example, if I create Class Foo, which has a string property of name, I'd like to instantiate Foo a = new a() by clicking Button1, and when I click Button2, I'd like to be able to MessageBox.Show(a.name). There may be multiple instances of Foo, if that matters at all.
What is my best option for being able to use class instances in such a way?
A private field or property of a class satisfies the requirement - such field can be accessed by all methods of the class.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
foo a;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
a = new foo();
a.name = "bar";
}
private void button2_Click(object sender, EventArgs e)
{
if (a != null && a.name != null)
MessageBox.Show(a.name);
else
MessageBox.Show("");
}
}
public class foo
{
public string name { get; set; }
public foo() { }
}
}
If you want this variable to be accessible to other forms you'd need to make it public (preferably as property) - C# winform: Accessing public properties from other forms & difference between static and public properties
maybe you just want a static class
Winforms are nothing but some graphical elements backed by code. The code can own/create objects just like regular 'non-winform' code. The same scoping rules apply.
My guess if yours is more a problem of 'how does my form access shared state defined outside of it'? Create a static class, or have a setter on the class of your form that other code can use to set this shared state.
A form you create is just another class, derived from Form. A class exists in a given namespace, so you just need to create your Foo class in a namespace shared by your application's forms.
If a class is shared by multiple forms, then usually you'd separate out that class into a separate file.
Jon Skeet [C# MVP]
Guest Posts: n/a
2: May 15 '07
re: Application variables in csharp.
On May 15, 12:04 pm, Control Freq
wrote:
Quote:
Still new to csharp. I am coming from a C++ background.
>
In C++ I would create a few top level variables in the application
class. These are effectively global variables which can be accessed
throughout the application because the application object is known.
>
What is the csharp equivalent of this practice?
I can't seem to add variables to the "public class Program" class and
get access to them from other files.
>
I am probably missing something obvious.
Basically you want public static fields (or preferably properties).
An alternative to this is a singleton:
http://pobox.com/~skeet/csharp/singleton.html
Jon
When in doubt, find something signed by John Skeet. Found on: http://bytes.com/topic/c-sharp/answers/646865-application-variables-csharp

Categories