I am currently making some basic incremental game in c# in WFA. Here's the code:
namespace Xadrs
{
public partial class Form1 : Form
{
public void Ref()
{
label2.Text = Points.ToString();
button2.Text = "Level up! (" + Upgradeprice.ToString() + ")";
label4.Text = Upgrade.ToString();
label6.Text = Upgradeautoclick.ToString();
button4.Text = "Level up PPS! (" + Upgradeautoclickprice.ToString() + ")";
}
public int ach_beginner = 0;
public int ach_intermediate = 0;
public int ach_expert = 0;
public int ach_master = 0;
int Points = 0;
int Upgrade = 1;
int Upgradeautoclick = 0 ;
int Upgradeautoclickprice = 110;
int Upgradeprice = 25;
public Form1()
{
InitializeComponent();
Ref();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (Upgrade == 5)
{
Points++;
Ref();
}
}
private void button1_Click(object sender, EventArgs e)
{
Points += Upgrade;
Ref();
}
private void button2_Click(object sender, EventArgs e)
{
if (Points >= Upgradeprice)
{
Upgrade += 1;
Points -= Upgradeprice;
Upgradeprice += Upgradeprice / 4;
}
else
{
MessageBox.Show("Not Enough Nico points...");
}
Ref();
if (Upgrade == 5)
{
MessageBox.Show("Beginner: Reach 5 PPS.\nReward: AutoClick!", "ACHIEVEMENT UNLOCKED!");
ach_beginner = 1;
timer1.Enabled = true;
Upgradeautoclick = 1;
button4.Visible = true;
Ref();
}
}
Form2 achievements = new Form2();
private void button3_Click(object sender, EventArgs e)
{
Form2.Show();
}
private void button4_Click(object sender, EventArgs e)
{
if (Points >= Upgradeautoclickprice)
timer1.Interval = timer1.Interval / 2;
Points -= Upgradeautoclickprice;
Upgradeautoclickprice += Upgradeautoclickprice;
}
and in form2 I want to have:
if (ach_beginner = 1)
{
//Text in this label = something like: Beginner - Reach 5 Points per click
labelwithachievement.Visible = true;
}
but the ach_beginner isn't declared in form2. I would like to somehow "connect" this integer to have its declaration from form1 in form2.
Don't think of it as sharing the integer itself, instead think of it as Form2 has a dependency on something in Form1.
Since the variable is currently public (we'll get to that in a minute), at the simplest all you need to do is provide Form2 with a reference to the instance of Form1. Put a property on Form2 and require a value in its constructor:
private Form1 form1Instance;
public Form2(Form1 form1)
{
this.form1Instance = form1;
}
Then when you create an instance of Form2, pass it a reference to the current instance of Form1:
Form2 achievements = new Form2(this);
Then in Form2 you can refer to its new member variable to get information from Form1:
if (this.form1Instance.ach_beginner == 1)
Note regarding public variables... It's generally considered best practice to expose properties publicly instead of variables. So replace this:
public int ach_beginner = 0;
with this:
public int Ach_Beginner { get; set; }
And update references to it accordingly. There are a variety of reasons for this, but ultimately the idea is that a class should hide its values and provide access to them rather than just provide the values themselves.
This is a pretty simple start to the idea of providing a dependency to an object, and there are a number of places you can go from here. For example, if you don't want to pass around entire forms as dependencies (since they include considerably more data/functionality than is otherwise needed for the dependency), you can encapsulate your values in an object of their own and pass around that object as the dependency.
Extrapolating from there, you can continue to separate business logic from UI elements (like forms and controls), and begin to move your logic into those business logic objects and components. This will make your logic more portable onto other UI platforms, easier to test, etc.
For example, suppose you have a class such as:
public class LevelInfo // guessing on an appropriate name here
{
public int Ach_Beginner { get; set; }
public int Ach_Intermediate { get; set; }
public int Ach_Expert { get; set; }
public int Ach_Master { get; set; }
}
Then in Form1 you use that object instead:
private LevelInfo levelInfo = new LevelInfo();
// elsewhere...
levelInfo.Ach_Beginner = 1;
// etc.
Then Form2 can require a reference to that object:
private LevelInfo levelInfo;
public Form2(LevelInfo level)
{
this.levelInfo = level;
}
and use that object:
if (this.levelInfo.Ach_Beginner == 1)
At this point LevelInfo is de-coupled from the UI and can contain portable business logic/information.
All you need is a Parameter. You call the Form2.Show Method. As any other Method a method of Form2 can become a parameter. So in Form2 you could do the following:
public void Show(int ach_beginner)
{
//Do sth. with your int
this.Show();
}
If you call Form2 on Form1 now you can pass your integer:
private void button3_Click(object sender, EventArgs e)
{
Form2.Show(ach_beginner);
}
I think this is the easiest approach. Instead of overriding the Show Method you could make a Property as well. In Form2 declare:
public int AchBeginner {get;set;}
In Form1 you set this value before you call the Show Method:
private void button3_Click(object sender, EventArgs e)
{
Form2.AchBeginner = ach_beginner;
Form2.Show();
}
As David explained in comments, the value won't be updated on Form2. If you want to achieve this you could use an Interface:
public interface IBeginner
{
int AchBeginner{get;set;}
}
public void Form1 : Form, IBeginner
{
public int AchBeginner{get;set;}
//The place you create Form2
Form2.Beginner = this;
}
public void Form2 : Form
{
public IBeginner Beginner{get;set;}
//Here you can access
int achBeginner = Beginner.AchBeginner:
}
UPDATE
Based on the comment from the question author i think an event would be the most usefull think. So you can tell your Form2 that your character on Form1 reaches level 5. For example:
public class LevelEventArgs : EventArgs
{
public int Level {get;}
public LevelEventArgs(int level)
{
Level = level;
}
}
//Form1 need to implement an Event which later can notify any subscriber (Form2 in this case)
public class Form1 : Form
{
public event EventHandler<LevelEventArgs> LevelUp;
//When your character reach new level do following:
LevelUp?.Invoke(this, new LevelEventArgs(ach_beginner));
//Show Form2
Form2 form = new Form2(this);
form.Show();
}
Form2 needs to subscribe this event now. For this you need to put Form1 to Form2 (or better an Interface as described above)
public class Form2 : Form
{
public Form2(Form form1)
{
//Register Event LevelUp from Form1
form1.LevelUp += (args) =>
{
if (args.Level == 5)
//Level 5 reached
}
}
}
Related
There are two forms, a MainForm and a GraphicsForm.
In MainForm, there are "New" and "Save", "Open" buttons. When clicking the "New", a GraphicsForm created (When the "New" is clicked multiple times, multiple GraphicsForms are created).
The question is, when created multiple GraphicsForms, and the user only wants to save the content in one of them or open a content file to one of them, How to implement this?
MainForm.cs
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private ToolStripMenuItem _winMenuItem = new ToolStripMenuItem();
private GraphicsForm _graphicsForm;
private int _counter = 1;
private ContentDoc _contentDoc = new ContentDoc();
private void New_Click(objec sender, EventArgs e)
{
_winMenuItem.Name = "Win";
_winMenuItem.Text = "Windows";
int item = MainMenuStrip.Items.IndexOf(_winMenuItem);
if (item == -1)
{
MainMenuStrip.Items.Add(_winMenuItem);
MainMenuStrip.MdiWindowListItem = _winMenuItem;
}
_graphicsForm = new GraphicsForm(_contentDoc);
_graphicsForm.Name = string.Concat("Win_", _counter.ToString());
_graphicsForm.Text = _graphicsForm.Name;
_graphicsForm.MdiParent = this;
_graphicsForm.Show();
_graphicsForm.WindowState = FormWindowState.Maximized;
_counter++;
}
private void Save_Click(object sender, EventArgs e)
{
... // here
}
private void Open_Click(object sender, EventArgs e)
{
... // here
}
}
GraphicsForm.cs
public partial class GraphicsForm : Form
{
//ContentDoc is a class to manage all the graphics drawn by the user in the form.
private ContentDoc _contentDoc = new ContentDoc();
public GraphicsForm(ContentDoc contentDoc)
{
InitializeComponent();
_contentDoc = contentDoc;
}
private Canvas_MouseDown()
{
}
private Canvas_Paint()
{
}
...
The parent form has an ActiveMdiChild property, so you can use the to access the currently-selected GraphicsForm instance:
var activeGraphicsForm = ActiveMdiChild as GraphicsForm;
There are other variations you might use, e.g. pattern matching, depending on the specific details and your preference.
You can then put your saving logic in a public method in GraphicsForm and call it from the parent form. Alternatively, you can put your saving logic in the parent form and expose the data to be saved via one or more public properties in GraphicsForm.
I have one form in my software that is displaying the total value (it is a label), and I want to display the value of that label on another form.
Here is my code:
public void PresmetajTotal()
{
for (var i = 0; i < dataGridView1.Rows.Count; i++)
{
vkp += Convert.ToInt64(dataGridView1.Rows[i].Cells[4].Value);
lblTotal.Text = vkp.ToString();
}
}
And on the other form I created this:
private void Change_Load(object sender, EventArgs e)
{
Prodazba prodaz = new Prodazba();
label4.Text = prodaz.lblTotal.Text();
}
The error i get is :
CS0122 'Prodazba.lblTotal' is inaccessible due to its protection level
Add a public property in Prodazba form that will return the value of the label.
public partial class Prodazba()
{
public string Total { get { return lblTotal.Text; } }
//....
}
Then access it like:
private void Change_Load(object sender, EventArgs e)
{
Prodazba prodaz = new Prodazba();
label4.Text = prodaz.Total;
}
Tw things:
You are creating an new form with new Prodazba()
Your label is private
The second one is easier to deal with. In the form editor, or your designer code, set the access level to internal or public.
For the first one, you could take several approaches depending on how the forms are created. If your first form loads the Prodazba, you could:
public partial class YourMainForm
{
Prodazba prodaz;
then...
private void Change_Load(object sender, EventArgs e)
{
prodaz = new Prodazba();
prodaz.Load += delegate {this.label4.Text = prodaz.Total};
prodaz.Show();
}
If your label is internally accessable, you could run any event handler from it, like prodaz.label4.TextChanged += ...
I am new to c# and I just need something basic. I am trying to call a method from a button click and I don't know if I declare an object and method in Program.cs or Form1.cs
Here is what I have so far.
public partial class frmMain : Form
{
Form form = new Form();
public frmMain()
{
InitializeComponent();
}
private void btnCalc_Click(object sender, EventArgs e)
{
txtC.Text = form.CalcHypotenuse(double.Parse(txtA.Text), double.Parse(txtB.Text));
}
}
public string CalcHypotenuse(double sideA, double sideB)
{
double hypotenuse = Math.Sqrt((sideA * sideA) + (sideB * sideB));
string hypotenuseString = hypotenuse.ToString();
return hypotenuseString;
}
Methods need to be inside a class. Your form is a class so just put the method inside it and then you can call it. Please note I have moved the method inside the frmMain class and removed the line Form form = new Form(); since you do not need it.
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void btnCalc_Click(object sender, EventArgs e)
{
// the 'this' is optional so you can remove it
txtC.Text = this.CalcHypotenuse(double.Parse(txtA.Text), double.Parse(txtB.Text));
}
public string CalcHypotenuse(double sideA, double sideB)
{
double hypotenuse = Math.Sqrt((sideA * sideA) + (sideB * sideB));
string hypotenuseString = hypotenuse.ToString();
return hypotenuseString;
}
}
If you are only calling the method from within your form only, then make it private too so it can not be called from outside.
how do I access form1 string variable from a different class?
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
public string deva = "123";
//button
private void button8_Click(object sender, EventArgs e)
{
deva = "456";
}
private void button9_Click(object sender, EventArgs e)
{
Other ks = new Other();
ks.test_me();
}
}
public class Other: Form1
{
//trying to access Form1 variable.
public void test_me()
{
Form1 fm = new Form1();
MessageBox.Show(fm.deva);
//deva is 123 but not 456.
//I clicked on button and values changes it form1 however from here it assigns just default value
}
//
//Does creating a new form1 will reset its values?
//Somebody please help me. how to solve this issue.
}
public partial class Form1: Form {
public Form1()
{
InitializeComponent();
}
public string deva = "123";
//button
private void button8_Click(object sender, EventArgs e)
{
deva = "456";
}
private void button9_Click(object sender, EventArgs e)
{
Other ks = new Other(this);
ks.test_me();
}
}
no need to inherit from form1, please pass the object via constructor
public class Other {
Form1 obj = null;
public Other(Form1 object)
{
this obj = object;
}
public void test_me()
{
MessageBox.Show(obj.deva);
}
}
Make your variable deva Static. Access it with Class directly not object.
public static string deva = "123";
public void test_me()
{
//Form1 fm = new Form1();
MessageBox.Show(Form1.deva);
}
Answer on the title question.
Read Jon Skeet's comment for explanation of reason why your approach not workiing.
If you want have access to the variables of another instance, then you need in someway have reference to that instance
One way pass it in the constructor of Other
public class Other: Form1
{
private readonly Form1 _Form1;
public Other(Form1 form1)
{
_Form1 = form1;
}
public void test_me()
{
MessageBox.Show(_Form1.deva);
}
}
Then where you create new instance of Other pass instance of your Form1 ti the constructor of Other
public class Form1
{
private void button9_Click(object sender, EventArgs e)
{
Other ks = new Other(this);
ks.test_me();
}
}
default value is set a every new instance
if you want to keep last value you make a static property
public static string deva = "123";
I'm a newbie in c# and visual studio, but not programming in general.
I searched for answer to my question for 3 days and I found plenty of them, but for some weird reason (I'm sure I'm missing something very obvious) I cannot get it to work.
I think it's the most basic question newbies like me ask.
I have a form (Form3) with a text box and a button (I set it up is just for testing purposes).
I want to populate and read this text box from another class. I understand the most proper way to do this is to create a property in Form3.cs with GET and SET accessors. I did that but I cannot get it to work. I'm not getting any error messages, but I'm not able to set the value of the text box either. It just remains blank.
Here's my sample code:
namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public string setCodes
{
get { return test1.Text; }
set { test1.Text = value; }
}
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{ }
private void button1_Click(object sender, EventArgs e)
{
a.b();
}
}
public class a
{
public static void b()
{
Form3 v = new Form3();
v.setCodes = "abc123";
}
}
}
Can someone lend me a hand solving this?
The problem is you are setting the value to a new instance of the form. Try something like this:
public partial class Form3 : Form {
public string setCodes
{
get { return test1.Text; }
set { test1.Text = value; }
}
private A a;
public Form3()
{
InitializeComponent();
a = new A(this);
}
private void button1_Click(object sender, EventArgs e)
{
a.b();
}
private void Form3_Load(object sender, EventArgs e)
{
}
}
public class A
{
private Form3 v;
public a(Form3 v)
{
this.v = v;
}
public void b()
{
v.setCodes = "abc123";
}
}
You're creating a brand new Form3() instance.
This does not affect the existing form.
You need to pass the form as a parameter to the method.
Try this:
public partial class Form3 : Form
{
/* Code from question unchanged until `button1_Click` */
private void button1_Click(object sender, EventArgs e)
{
a.b(this);
}
}
public class a
{
public static void b(Form3 form3)
{
form3.setCodes = "abc123";
}
}
This passes the current instance of the form to the other class so that it can update the setCodes property. Previously you were creating a new form instance rather than updating the current form.
Sending form instance to other other class
Form1 objForm1=new Form1();
obj.Validate(objForm1);
Easy way to access controls in another class by modifying Controls Private to Public in the Form(Designer.cs)