I'm very new to C#, passing arguments, modularizing and value-returning methods are pretty tought for me.
I'm trying to get two buttons to interact with each other.
One button has a counter on it. Each time it is clicked a variable that has started out with 1 gets added another one.
And the other button displays the number that the counter on the other button is on.
I hope this makes sense.
private void button_Click(object sender, EventArgs e)
{
}
private int TotalCount(int count)
{
return count += 1;
}
private void buttonCount_Click(object sender, EventArgs e)
{
int totalcount;
int count;
totalcount = TotalCount(ref count);
MessageBox.Show("The number clicked is: " + totalcount);
}
You'll need to make 'count' an instance variable...
int count = 0;
private void button_Click(object sender, EventArgs e)
{
}
private int TotalCount()
{
++count;
return count;
}
private void buttonCount_Click(object sender, EventArgs e)
{
int totalcount = TotalCount();
MessageBox.Show("The number clicked is: " + totalcount);
}
You were declaring 'count' as a local variable, so it was being initialized on each entry to the method, thus the value was not persistent. Reference arguments are not needed in this case, so they have been removed.
As Garry Vass points out reference arguments are not needed in this case however if you are using reference arguments both the definition and the calling of the method needs to specify ref
private int TotalCount(ref int count)
{
return count += 1;
}
Here is a reference that explains the ref keyword more completely.
http://msdn.microsoft.com/en-us/library/14akc2c7.aspx
Although Gary Vass is correct that count needs to be an instance variable, I wouldn't consider his answer as the right way to go about coding it.
Method names are critically important, especially as a code base grows, and you should follow the principle of "least astonishment". In this case the name of a method should indicate what it will do and it shouldn't have hidden side effects. See http://www.atalasoft.com/cs/blogs/stevehawley/archive/2006/02/27/9590.aspx
The name TotalCount implies that it will return the total count. Nothing about that name indicates that it is actually going to modify data.
The route I would take is:
int count = 0;
private int IncrementCount() {
count++;
return count;
}
private void buttonCount_Click(object sender, EventArgs e)
{
int totalcount = IncrementCount();
MessageBox.Show("The number clicked is: " + totalcount);
}
The difference is subtle. However, someone glancing through just the buttonCount_Click method would have a pretty good idea what IncrementCount() does without actually having to investigate that code.
Related
I have been trying to finish this small application for counting the number of attempts if you fail to write the correct pin code.
This is my code so far, and I am not understanding why my code isn't working and it keeps on incrementing non stop.
private void btn_login_Click(object sender, EventArgs e)
{
int attempts = 0;
int pin_number;
do
{
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (pin_number != 1326)
{
attempts++;
MessageBox.Show($"pin code is incorrect you have {attempts} of 3 attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
} while (pin_number == 1326 && attempts < 3);
}
Every time you click the button is an "attempt", correct? Well, what's the first thing you do every time you click the button...
int attempts = 0;
So every attempt is the first attempt. Except when the user gets it right. Then what you have is an infinite loop because the pin_number is correct and attempts is never incremented.
First, get rid of the loop entirely. There's no need to repeatedly check the same input. Once it's checked, it's checked. Second, track the number of attempts outside the scope of each attempt, such as at the class level. Third, check the number of attempts. Perhaps something like this:
private int attempts = 0;
private void btn_login_Click(object sender, EventArgs e)
{
int pin_number;
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (attempts < 3 && pin_number != 1326)
{
attempts++;
MessageBox.Show($"pin code is incorrect you have {attempts} of 3 attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
}
Now it's at least checking the pin as expected. Though at this point you have some logic to reconsider for your program. Off the top of my head...
It never notifies the user if they got the pin right. Perhaps something else should happen?
After the number of attempts is exhausted, there's no warning to indicate this. It looks exactly as it does if the pin is correct.
The text implies that the number of attempts is counting down, but it's actually counting up.
Perhaps something like this might get you started:
private int attempts = 3;
private void btn_login_Click(object sender, EventArgs e)
{
int pin_number;
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (attempts <= 0)
{
MessageBox.Show($"No more attempts left");
}
else if (pin_number != 1326)
{
attempts--;
MessageBox.Show($"Pin code is incorrect you have {attempts} attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
}
Examine each statement in the logic. For your own logic, particularly around if blocks and loops and whatnot, perhaps even grab a piece of paper and draw out the different code paths and write down in each path what should happen there. Every detail is important, such as when to show a message or when to modify a value. There's a lot of polish that can be added to this code, and I imagine it's an academic exercise so I'll leave that to you.
Right now you have a loop inside your button click handler. You probably don't want that since you want to enable the user to enter a new pin code and click the Login button again.
But that also means that you need to store the number of attempts outside the click handler, since it needs to be saved from one click to the next.
So if you change your code to something like this, I think you'll get the functionality you're after
private int attempts = 0;
private void btn_login_Click(object sender, EventArgs e)
{
int pin_number;
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (pin_number != 1326)
{
attempts++;
MessageBox.Show($"pin code is incorrect you have {3-attempts} of 3 attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
if (attempts >= 3)
{
btn_login.Enabled = false;
}
}
I've been creating a autocheckout bot, and I'm very new to C#, and coding in general. I've gotten pretty far, almost done with the program, or so I thought, and now I want to have the ability to create multiple tasks, or run the task method multiple times. I also want to be able to input a different "profile", which has defined strings, such as login email, password, ect., on each task seperately. I'm very stuck and I have no idea where to even begin, maybe if someone could point me in the right direction for me to get started? last time I got some amazing help from this community, and it helped me a lot. Here is my current attempt:
public void KeywordTask1()
{
Start();
LogIn();
FindProductByKeyword();
stopwatch.Start();
AddToCart();
Checkout();
TimeSpan CheckoutTime = stopwatch.Elapsed;
}
public void KeywordTask2()
{
Start();
LogIn();
FindProductByKeyword();
stopwatch.Start();
AddToCart();
Checkout();
TimeSpan CheckoutTime = stopwatch.Elapsed;
}
I have buttons that start those tasks, but I also want the varibles to change, like a status text that I have set in my windows form. here is my GUI if it helps you understand my code a bit better:
https://gyazo.com/c6e9334e04aeb223e0afade6da8bec4e
Please let me know if you need anything else from me! I'm not sure if this is allowed but I'm willing to pay for someone to help me through this, not very much because I'm only 16 haha, but anyway, Thank you!
Well, I am not sure if this is what you want but if you want to run method with different variable value then create method:
public void MyMethod(string myVariable)
{
//do something with myVariable
}
And you can pass different variable value when calling method:
MyMethod("123abc");
or something like:
var newVariable="123abc"
MyMethod(newVariable);
To start method with different input create method with variable
public void MyUsername(string username)
{
MessageBox.Show(username);
}
private void buttonUsername1_Click(object sender, EventArgs e)
{
MyUsername("Adam");
}
private void buttonUsername2_Click(object sender, EventArgs e)
{
MyUsername("Jack");
}
To start method multiple time use loop
private void btnDoAllTask_Click(object sender, EventArgs e)
{
int count = 0;
// run 5 times
while(count < 5)
{
count++;
MyUsername("username" + count.ToString());
}
}
or loop through array
private void btnDoAllTask_Click(object sender, EventArgs e)
{
var listUsername = new string[] { "one", "two", "three" };
foreach (var username in listUsername)
{
MyUsername(username);
}
}
I want to move picturebox with thread programming. Also, I want to get Picturebox's count with a Textbox in my solution, but it's my first try so I have problems with it. Could you please help me?
Thread th;
public void F_Thread()
{
for (int i = 0; i < Convert.ToInt16(textBox1.Text); i++)
{
this.pictureBox1.Left = this.pictureBox1.Left - 10;
Thread.Sleep(100);
}
}
private void button1_Click_1(object sender, EventArgs e)
{
th = new Thread(F_Thread);
th.Start();
}
Here is a cheap, minimal example of using Invoke to change a property of a control from a different thread:
public void F_Thread()
{
for (int i = 0; i < Convert.ToInt16(textBox1.Text); i++)
{
if (pictureBox1.InvokeRequired )
this.Invoke(new UpdatePBInvoker(UpdatePB), -10);
Thread.Sleep(100);
}
}
delegate void UpdatePBInvoker(int moveX);
private void UpdatePB(int moveX)
{
pictureBox1.Left = pictureBox1.Left + moveX;
}
Feel free to add more parameters; just make sure to keep the signatures of the function and the delegate the same:
delegate void UpdatePBInvoker(Control ctl, int moveX);
private void UpdatePB(Control ctl, int moveX)
{
ctl.Left = ctl.Left + moveX;
}
Call the 2nd version like this:
.. this.Invoke(new UpdatePBInvoker(UpdatePB), pictureBox1, -10);
Note the the check if ( someControl.InvokeRequired ) is optional and often added to allow for the option of not calling the function from a different thread; for theses cases one usually adds an else branch with the direct call: UpdatePB(...)
Also note that the thread may still run when you close the Form. To prevent errors make sure to abort it, maybe like this:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if ((th!= null && th.IsAlive) th.Abort();
}
If your thread would do more complicated things, especially aquiring locks, it should not be aborted but given a chance to finish and close itself, usually by setting a global flag. But in this case it should work ok. Also see MSDN on this topic..
Hi I'm very new to c# and I was hoping someone could point me in the right direction. I have created a text box with the value "Total" set to 0 in my main class, and I have created a button "button1_Click" in my "AddFunds" class in which I want it to change the Total value by reading in what the user has in putted "Deposit" putting through a loop and incrementing the "Total". How do I get the AddFunds class to recognize the int Total in my main class?
public void textBox1_TextChanged(object sender, EventArgs e)
{
int Total = new int();
Total = 0;
////string str = Convert.ToString(Total);
////Total.Text = str;
}
public void button1_Click(object sender, EventArgs e)
{
for (int Deposit = 0; Deposit <= 0; ++Deposit)
{
Total = Deposit;
}
}
public void richTextBox1_TextChanged(int initialDeposit)
{
int Deposit = int.Parse(Console.ReadLine());
}
You have some ways of doing that, but remember if this classes you're talking about are forms, they need to exist simultaneously, anything else will end up on you trying to access a null reference.
You can create a public property Total on your main class and pass an instace of Main to AddFund
If the composition is the oposite as the above, and Main holds an instance of AddFund you can make Main inject itself on the other class or pass a Funciotn to AddFund so it can access the value
This one is the only one that doesn't sound like a code smell given the information you provided, abstract your logic to some classes that are not forms and manipulate them on the forms.
In my program there are multiple players who's stats can all be increased at the same time.
Player 1 is represented by staminaTextBox[0] skillTextBox[0] LuckTexBox[0]
Player 2 is represented by staminaTextBox[1] skillTextBox[1] LuckTexBox[1]
etc.
I need my IncreaseStat method to deal with 3 different type of Textbox Overload e.g. Stamina, Skill, Luck
private void StaminaIncBtn_Click(object sender, EventArgs e)
{
IncreaseStat(staminaText[0]);
}
private void LuckIncBtn_Click(object sender, EventArgs e)
{
IncreaseStat(luckText[0]);
}
private void IncreaseStat(TextBox statText)
{
for (int i = 0; i < 5 ; i++)
{
statText[i].Text = "Altered";
}
}
This method is used to increase all 5 players stats at the same time.
It works fine if they are not control arrays, however I need them to be. I get the error
"Cannot apply indexing with [] to an expression of type 'System.Windows.Forms.TextBox". It applies to that fact that inside the method I am saying statText[i].
I do not understand how to get around this problem. Any suggestions would be more than welcome.
Thank you for your time.
Would this be sufficient (with possible changes by yourself for your need)?
private void IncreaseStat() {
foreach (TextBox textBox in this.Controls.OfType<TextBox>().Where(x => x.Name.Contains("stamina") ||
x.Name.Contains("skill") ||
x.Name.Contains("Luck"))) {
textBox.Text = "Altered";
}
}