Increment number per button click C# Desktop - c#

I'm trying to create a mathematical game with a timer that calculates the number of correct questions within a specific time. Now I'm trying to increment an int value per button click if the answer is correct.
But it only increment once and sometimes does not increment:
private void button1_Click(object sender, EventArgs e)
{
int x = Randomnumber.Next(12);
int z = Randomnumber.Next(12);
int s = x * z;
int correct = 0;
//int cv = +correct;
textBox2.Text = x.ToString();
textBox3.Text = z.ToString();
if (s == Convert.ToInt32(textBox4.Text))
{
correct += 1;
numbercorrect.Text = correct.ToString();
}
}

your main form(i'm assuming you're using forms) is a class.
What I'd suggest is declaring a variable as a member of your forms class, and using that to hold the number of correct responses.
I'd imagine something like the following;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
int correct;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//insert logic here
correct++;
}
}
}

You need to move int correct declaration to class scope. Otherwise with every click, you start with new variable.

int correct = 0; is scoped within the function. Move it outside the function as a class field. That way it will preserve its value instead of being reset to 0 during each click.

Try this:
private int correct = 0;
private void button1_Click(object sender, EventArgs e)
{
int x = Randomnumber.Next(12);
int z = Randomnumber.Next(12);
int s = x * z;
//int cv = +correct;
textBox2.Text = x.ToString();
textBox3.Text = z.ToString();
if (s == Convert.ToInt32(textBox4.Text))
{
correct ++;
numbercorrect.Text = correct.ToString();
}
You always start your count with 0, and never get the original value.
Now the variable holding the data is outside the function and initialized when the form loads.

Every time the button is clicked, correct is beging reset to zero.
Try declaring correct outside of the method.

Try look at code bellow:
int correct = 0;
tryParse(numbercorrect.Text, out correct);
So your code must be like:
private void button1_Click(object sender, EventArgs e)
{
int x = Randomnumber.Next(12);
int z = Randomnumber.Next(12);
int s = x * z;
int correct = 0;
int.tryParse(numbercorrect.Text, out correct);
//int cv = +correct;
textBox2.Text = x.ToString();
textBox3.Text = z.ToString();
if (s == Convert.ToInt32(textBox4.Text))
{
correct += 1;
numbercorrect.Text = correct.ToString();
}

Related

Data from dynamically added parsed textboxes

I'm making a simple calculator to save myself from having to add up a bunch of invoice totals on basic calculator at work (since we use paper invoices). I'm just getting the basic functionalities in place currently and one of the functions I have is adding extra textboxes and then later trying to add all of the values in the textboxes to a subtotal. The problem I am having (I think) is that the compiler needs to have the the textbox ID's before the program is compiled. I'm also going to apologize for the sloppy variable names, I tried everything I could think of in my basic mindset until 4AM and by the time I was just using any variable. I've tried all the iterations, (ended up with do while statement as you can see).
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
int partboxes = 3;
int lastY = 83;
public Form1()
{
InitializeComponent();
}
private void buttonFinal_Click(object sender, EventArgs e)
{
AddParts();
}
public double AddParts()
{
int i = 1;
double megavalue = 0;
do
{
double totalsum = double.Parse(("partBox" + i).Text);
megavalue = totalsum + megavalue;
i = i + 1;
} while (i < partboxes);
string supervalue = megavalue.ToString();
lblPartsTotal.Text = supervalue;
return megavalue;
}
private void button1_Click(object sender, EventArgs e)
{
TextBox partBox = new TextBox();
partBox.Name = "partBox" + partboxes++;
partBox.Location = new System.Drawing.Point(12, lastY + 26);
partBox.Size = new System.Drawing.Size(100, 20);
// Add the textbox control to the form's control collection
this.Controls.Add(partBox);
lastY = lastY + 26;
partboxes = partboxes++;
}
}
}
You can get a textbox by name from the Controls property with
var tb = (TextBox)Controls["partBox" + i];
where i is the textbox number.
The indexer returns a Control. But since every control has a Text property, you can use it without casting.
double totalsum = double.Parse(Controls["partBox" + i].Text);
See: Control.ControlCollection Class

Creating a game of Checkers

I am creating this in regards to an issue I just ran in with. I am trying to create a primitive game of checkers using only buttons and so far I am just testing how to get the program to recognize selecting a button and moving the piece.
My Code:
private void Checkers_Load(object sender, EventArgs e)
{
}
string selectedChecker = "";
string currentButton = "";
int blankSpace = 0;
int[] Board = new int[64];
private void gameBoard()
{
foreach(var control in Controls)
{
var button = control as Button;
if(button != null)
{
if(button.Name == currentButton)
{
button.Image = System.Drawing.Image.FromFile("Red Checker.png");
}
else
{
MessageBox.Show("Dead.");
}
}
else
{
MessageBox.Show("Dead.");
}
}
}
private void attemptMove()
{
string substringChecker = null;
substringChecker = selectedChecker.Substring(0,2);
int selectedCheckerNumber = Convert.ToInt32(substringChecker);
string substringButton = null;
substringButton = currentButton.Substring(0,2);
int currentButtonNumber = Convert.ToInt32(substringButton);
if((selectedCheckerNumber + 3 == currentButtonNumber) || (selectedCheckerNumber + 4 == currentButtonNumber))
{
Board[currentButtonNumber] = Board[selectedCheckerNumber];
Board[selectedCheckerNumber] = blankSpace;
gameBoard();
}
}
private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
{
int w = pictureBox1.Size.Width;
int h = pictureBox1.Size.Height;
int count = 8;
Bitmap b = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
w /= count;
h /= count;
Graphics g = Graphics.FromImage(b);
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
Color c = (i + j) % 2 == 0 ? Color.Red : Color.Black;
Brush br = new SolidBrush(c);
g.FillRectangle(br, i * w, j * h, w, h);
br.Dispose();
}
}
g.Dispose();
pictureBox1.Image = b;
pictureBox1.Refresh();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
//Close form
this.Close();
}
private void howToPlayToolStripMenuItem_Click(object sender, EventArgs e)
{
//MessageBox.Show("How to play a game of Checkers: Step 1 - Don't play.");
}
private void informationToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void checkerSpace18_Click(object sender, EventArgs e)
{
}
private void checkerSpace17_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
string buttonClicked = btn.Name;
if (selectedChecker == "")
{
selectedChecker = buttonClicked;
}
else
{
currentButton = buttonClicked;
attemptMove();
}
}
}
My question goes with regards to my attemptMove() method. I run into a runtime error:
"An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll. Additional information: Input string was not in a correct format."
It seems to occur whenever I go to move the piece to the other cell adjacent to the piece after moving it once. It may be because my program is not updating the pictures of the buttons when the buttons switch, but I wanted to see if any guidance could be shed upon this issue.
You are setting the "selectedChecker" to the clicked button .Name property. Then you are using substring(0,2) to get the first 2 characters and try to convert that to an integer.
Since a Name property can't start with numbers, you are attempting to convert some random text to an integer property.
A better approach would be to use the Tag property to hold information about the number, this can be any value. You can then use the int.Parse to parse the Tag value of the button.
What is your naming convention for the buttons? Seems like you're trying to get a number from the name, but the conversion is failing.
If the button names are button00 through button63, then you should be able to get the number using Substring, starting at Name.Length - 2. Note that you must have all button names use a two digit number at the end (00, 01, 02, etc).
For example:
// Get the last two characters of the button name
string substringChecker = selectedChecker.Substring(selectedChecker.Length - 2);
// Convert the characters to an integer
int selectedCheckerNumber = Convert.ToInt32(substringChecker);

Using a variable outside a function

I am making an algebra equation solver in which you enter 2 values and gives you the x value in a format of x + (value1)= (value2).
I figured out how to convert the data given in value1 and value2 to an integer but value one gets stuck in a private void and I can't use it outside of that void. How am I able to use value1 and value2 outside their respective private voids?
If you figured that out, how am I able to output the value of x into the program windows ( I'm creating a windows form application)?
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 equation_solver
{
public partial class EquationSolver : Form
{
public EquationSolver()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
int z;
z = Convert.ToInt32(textBox1.Text);
z = int.Parse(textBox1.Text);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
int y;
y = Convert.ToInt32(textBox1.Text);
y = int.Parse(textBox1.Text);
}
}
}
Define y and z at class level and then use that in different events.
public partial class EquationSolver : Form
{
int z = 0; //class level
int y;
public EquationSolver()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
z = Convert.ToInt32(textBox1.Text);
z = int.Parse(textBox1.Text);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
y = Convert.ToInt32(textBox1.Text);
y = int.Parse(textBox1.Text);
}
}
In your current code since you are defining them inside a method they are limited to their scope and not visible outside of their scope.
EDIT: Just noticed one thing in your code (thanks to #Rahul Tripathi), you are converting TextBox values to int using Convert.ToInt32 and int.Parse, both would have the same effect, you can use either of them, just don't use both. You can also look at int.TryParse for parsing which is safer options since it will not raise the exception if parsing fails.
well the answer is as Habib said, as the variable is created inside the method, they are limited to that scope. if you want it to be available outside the method, create them outside the method.
second point i do not get why are you using those two even handlers. You could have used two text boxes for y and z and a third text box for x and a button for the result.
public partial class EquationSolver : Form
{
int x, y, z;
//Button in the form named btnSolveForX
private void btnSolveForX_Click(object sender, EventArgs e)
{
y = Int.Parse(txtY.Text);
z = Int.Parse(txtZ.Text);
x = z - y; // As x + y = z -> x = z -y
txtX.Text = z.ToString();
PrintResultInConsole();
}
//This function is to show that the x is still available
//outside the scope of the functions as it is created
//in the scope of class which means it is available anywhere
//inside the class.
private void PrintResultInConsole()
{
Console.WriteLine("Value of x is {0}",x);
}
}
Obviously it is better to use int.TryParse method instead of Int.Parse method to convert string to integer as there is no guarantee that the user is going to enter valid integer values.
Don't use a void method. Use a function to return the values you need. Then call that function when your event is fired. Here's an example that uses a generic collection:
//Here is the code that defines the method:
private double Sum(List<double> dataEntries)
{
double total = 0;
foreach (double d in dataEntries)
{
total += d;
}
return total;
}
// Here is the code that calls the method:
List<double> myList = new List<double>();
myList.Add(5.3);
myList.Add(3.34);
myList.Add(3.453);
double mySum = Sum(myList);
MessageBox.Show(mySum.ToString());

code improvement - naming textboxes generated form numericupdown & button click

I have a problem with a code that is regarding adding controls with numericUpDown ( for example- if numericUpDown value equals to 3, user recievs 3 textboxes).
Thanks to stackoverflow users I improved my code.
Before improvement it looked like this:
private void button1_Click(object sender, EventArgs e)
{
if (numericUpDown1.Value == 1)
{
txtbx1.AutoSize = true;
Controls.Add(txtbx1);
txtbx1.Location = new Point(70, 100);
}
else if (numericUpDown1.Value == 2)
{
txtbx1.AutoSize = true;
Controls.Add(txtbx1);
txtbx1.Location = new Point(70, 100);
txtbx2.AutoSize = true;
Controls.Add(txtbx2);
txtbx2.Location = new Point(70, 130);
}
else if (numericUpDown1.Value == 3)
{
txtbx1.AutoSize = true;
Controls.Add(txtbx1);
txtbx1.Location = new Point(70, 100);
txtbx2.AutoSize = true;
Controls.Add(txtbx2);
txtbx2.Location = new Point(70, 130);
txtx3.AutoSize = true;
Controls.Add(txtbx3);
txtbx3.Location = new Point(70, 160);
}
}
After improvement:
private void button1_Click(object sender, EventArgs e)
{
int y = 100;
int x = 70;
for (int i = 0; i < numericUpDown1.Value; i++)
{
var txtbx = new TextBox();
txtbx.AutoSize = true;
Controls.Add(txtbx);
txtbx.Location = new Point(x, y);
// Increase the y-position for next textbox.
y += 30;
}
}
Now the problem is that I don't know how assign names to genarated textboxes.
(before the improvement I could name them - txtbx1, txtbx2, txtbx3...)
Code to improve:
private void button3_Click(object sender, EventArgs e)
{
try
{
double a, b, c, sum;
a = double.Parse(txtbx1.Text);
b = double.Parse(txtbx2.Text);
c = double.Parse(txtbx3.Text);
sum = a + b + c;
label1.Text = sum.ToString();
}
catch (Exception ex)
{
MessageBox.Show("error");
}
Please note that I'm a beginner, learning c# by watching youtube tutorials ;) I do realize that my question might be silly but I couldn't handle this problem by myself.
In advance thank you for your time and help.
If you need to access them afterwards, you have some options.
I'll guess that your objective is to set label1's text to the sum of the values contained in the specified textbox(es).
On the ValueChanged event of your NumericUpDown, check the delta and consequentely add or remove the required number of TextBoxes to your Form's Controls. To obtain the delta, you'll need to store the previous value of the NumericUpDown, and then subtract it from the current value. (If it was 5, and now it's 4, 4 - 5 = -1. A textbox has been removed).
private int _oldNUDvalue = 0; //or assign it to the default value
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
int delta = (int)numericUpDown1.Value - _oldNUDvalue;
if (delta < 0)
{
for (int i = -delta; i > 0; i--)
{
var tbox = Controls.Find("ntextBox" + (_oldNUDvalue - i), false)[0];
Controls.Remove(tbox);
}
}
else if (delta > 0)
{
for (int i = _oldNUDvalue; i < _oldNUDvalue + delta; i++)
{
var tbox = new TextBox();
tbox.Location = new Point(15, 55 + (30 * i));
tbox.Name = "ntextBox" + i;
Controls.Add(tbox);
}
}
_oldNUDvalue = (int)numericUpDown1.Value;
}
If, however, you only have a maximum number of 3, you could take a slightly different approach. My solution works with n-textboxes.
Finally, to get the TextBoxes' values from code, you have three approaches:
Loop through your Form's controls, check for TextBoxes with their name starting with "ntextBox", and add their values together
Use LINQ to do the same
Access them singularly via "Controls.Find("ntextBoxX", false)", where X is the number of course.
I'll show the LINQ approach as I like it better.
int sum = Controls.Cast<Control>().Sum(c => c.Name.StartsWith("ntextBox") ? int.Parse(c.Text) : 0);
I haven't tested the code, but it should work. Tell me if there are any problems.
EDIT: Tested and it works. For the sake of completeness, I'll add some event logic to the TextBox-adding loop, to make sure that their input is actually numeric.
tbox.TextChanged += HandleNTextBoxInput; // add this line
And elsewhere, add this method:
void HandleNTextBoxInput(object sender, EventArgs e)
{
string text = ((TextBox)sender).Text;
if (!Regex.IsMatch(text, "^[1-9][0-9]*$")) //Text is NOT numeric. Remove [1-9] if you want to keep leading zeros.
{
//Set the Text to 0, for example. Or show a message box. Or whatever.
((TextBox)sender).Text = "0";
}
}
As I mentioned in a comment- this code seems to be maybe too advanced for me.
I have no problem with adding the controls, bu still there is a problem how to get the sum from a button click to a textbox.
I probably made some simple mistakes, or something is missing but I really don't know how to fix this problem.
My code:
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.Text.RegularExpressions;
namespace testprogram
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) // I'm guessing something is missing over here
{
int sum = Controls.Cast<Control>().Sum(c => c.Name.StartsWith("ntextBox") ? int.Parse(c.Text) : 0);
}
void HandleNTextBoxInput(object sender, EventArgs e)
{
string text = ((TextBox)sender).Text;
if (!Regex.IsMatch(text, "^[1-9][0-9]*$")) //Text is NOT numeric. Remove [1-9] if you want to keep leading zeros.
{
//Set the Text to 0, for example. Or show a message box. Or whatever.
((TextBox)sender).Text = "0";
}
}
private int _oldNUDvalue = 0; //or assign it to the default value
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
{
int delta = (int)numericUpDown1.Value - _oldNUDvalue;
if (delta < 0)
{
for (int i = -delta; i > 0; i--)
{
var tbox = Controls.Find("ntextBox" + (_oldNUDvalue - i), false)[0];
Controls.Remove(tbox);
}
}
else if (delta > 0)
{
for (int i = _oldNUDvalue; i < _oldNUDvalue + delta; i++)
{
var tbox = new TextBox();
tbox.Location = new Point(15, 55 + (30 * i));
tbox.Name = "ntextBox" + i;
tbox.TextChanged += HandleNTextBoxInput;
Controls.Add(tbox);
}
}
_oldNUDvalue = (int)numericUpDown1.Value;
}
}
}
}

C# change labels created in public class from form button click

Having hard time understanding classes and why I can't access certain object.
How can i modify the code so I can change "map"(which is a bunch of labels) properties in all of my classes/events?
The method Draw2d() creates a couple of labels on the main form that I wish to change on different events(button click in this example).
Can someone help me, or just hint me into the right direction.
The Code:
public partial class Form1 : Form
{
public void Draw2d()
{
const int spacing = 20;
Label[][] map = new Label[5][];
for (int x = 0; x < 5; x++)
{
map[x] = new Label[5];
for (int y = 0; y < 5; y++)
{
map[x][y] = new Label();
map[x][y].AutoSize = true;
map[x][y].Location = new System.Drawing.Point(x * spacing, y * spacing);
map[x][y].Name = "map" + x.ToString() + "," + y.ToString();
map[x][y].Size = new System.Drawing.Size(spacing, spacing);
map[x][y].TabIndex = 0;
map[x][y].Text = "0";
}
this.Controls.AddRange(map[x]);
}
}
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
Draw2d();
}
private void button1_Click(object sender, EventArgs e)
{
map[0][0].Text = "1"; // <-- Doesn't work
}
}
Thanks!
you have to declare the map as property(global to class)
public partial class Form1 : Form {
public Label[][] map;
....
}
then you can use inside class like
this->map[...][...]
or from outside like
objClass->map[...][...]
My guess is that you added
public Label[][] map;
but forgot to change the second line of Draw2d from
Label[][] map = new Label[5][];
to
map = new Label[5][];
I just tried your code, and it works fine if you change those two lines. If that's not the problem, could you say what error you're getting, please?

Categories

Resources