My form doesn't loop this correctly - c#

I can't seem to get this loop to work.
Once the submit button is clicked ten times it should revert to the main form; instead it's reverting as soon as the submit is clicked once.
private void submit_Click(object sender, EventArgs e)
{
Form1 mainMenu = new Form1();
int repeat = 0;
do
{
num1.Text = A1.firstRandomNumber().ToString();
num2.Text = A1.secondRandomNumber().ToString();
repeat++;
} while (repeat <= 10);
if (repeat == 11)
{
mainMenu.Show();
this.Hide();
}
}

Everything inside of submit_Click occurs for each click. That includes defining repeat anew, setting it to 0, looping to increment it entirely to 11, and swapping which form is visible.
If you want to count the number of clicks, you'll have to establish your counter outside of the handler so it can be incremented:
private int repeatSubmit = 0;
private void submit_Click(object sender, EventArgs e)
{
if (repeatSubmit < 10)
{
num1.Text = A1.firstRandomNumber().ToString();
num2.Text = A1.secondRandomNumber().ToString();
repeatSubmit++;
}
else
{
mainMenu.Show();
this.Hide();
repeatSubmit = 0; // ready for the next time `this` form is shown
}
}

Just to clarify, you are waiting for the user to click the button 10 times? Or the loop is supposed to simulate 10 clicks?
This loop will enter (do) and set num1 and num2, add one to repeat, and then do that 10 times until repeat == 11, and then it will display the main menu.
I think the code you make be looking for is as follows:
private void submit_Click(object sender, EventArgs e)
{
...
repeat ++;
num1.Text = A1.firstRandomNumber().ToString();
num2.Text = A2.secondRandomNumer().ToString();
if(repeat >=10)
{
mainMenu.Show();
this.Hide();
}
}

As your code is, on 1 click you enter your loop where you proceed to increment the counter until it's equal to 11, then you exit your loop and show the main menu. Basically you're not counting clicks.
What you want to do is store the counter somewhere, probably as a class variable. Then every time you enter the click function you increment. When the click function has been entered 10 times then you would go into your if statement.
private int clickCount = 0;
private void submit_Click(object sender, EventArgs e){
clickCount++;
// Other code that happens on a click
if (clickCount == 10){ // 10th click show main menu
// Code to show main menu
}
}

It runs through the loop on the first click of submit, if I understand what you are trying to achieve, you don't need a loop at all, just a counter for each time the button is pressed.

Related

How do I capture the "Enter" key in a windows form?

I am trying to get the text of a textbox and save it to a variable when the user presses the enter key (when the textbox has info and is focused) since this is already inside a method i haven't been able to put another method inside like txtbox1_keypress (or i've been doing it wrong) so I need to be just code lines that i can insert in this method
private void df1_Click(object sender, EventArgs e)
{
txtres.Focus();
//timer
timeLeft = 50;
timer1.Start();
//mult
do
{
ban = 0;
m1 = r.Next(1, 4);
txtm1.Text = m1.ToString();
m2 = r.Next(2, 6);
txtm2.Text = m2.ToString();
res = m1 * m2;
//here is where i want to read txtm2 and continue with the rest
if(txtres.Text == res.ToString())
{
pun++;
}
ban++;
} while (timeLeft > 0 || ban != 10);
if(pun == 10 && level == 0)
{
level++;
System.IO.File.WriteAllText(#".\level.lvl", level.ToString());
}
}
Since you mentioned you want to run it inside KeyPress event, here is the example:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (int) Keys.Enter)
{
//do the logic
}
}
Add a button as the accept button of the form, this will trigger whenever enter is pressed.
Also, your loop (do -- while) should be done within the timer1_tick method, and take out the loop, the timer will execute the code within every interval it ticks until the timer reaches your maximum of 50.
As was mentioned, the loop will kill your GUI and it wont allow input.

Add number when button was clicked

I made an application which calculate the total price, I want that when the button is clicked, it add 1 to the quantity, but it only add 1 and when I click the button again, It doesn't add, Is there a way to loop a button?
here is my sample code
int intclicks;
private void button10_Click(object sender, EventArgs e)
{
intclicks++;
int qty = 1;
{
if (intclicks > 0)
{
int totalqty;
totalqty = qty + 1;
textBox3.Text = totalqty.ToString();
totalPrice();
}
}
}
the totalPrice(); sets display the total price in another textBox,
thanks.
You assign qty =1 in the beginning of the event, so, yes it starts from the beginning.
There is too much missing here, but it seems like you can use:
int qty = int.Parse(textBox3.Text);
...
When you click a button in a GUI-program, it fires the event once. Looping in the ClickEvent seems not very useful, as it would be blocking the main-thread and so your UI would freeze.
You could start a thread which loops in the background. See MSDN for threading.
Please explain further what you want to achieve.
That is because you have set int qty= 1 before your loop start and in your if condition you are checking if (intclicks > 0). So when you first time click the button it will check if (intclicks > 0) but as you have set qty = 1 the condition will be false and it wont go in the if condition. So change if condition to
if (intclicks >= 1)
I think your logic is a little out here for what (I believe) you are trying to do, why not try.
int intclicks;
int totalqty;
private void button10_Click(object sender, EventArgs e)
{
intclicks++;
if (intclicks > 0)
{
totalqty++
textBox3.Text = totalqty.ToString();
totalPrice();
intclicks = 0;
}
}

How to make text display in a textbox multiple times in C#?

I want to display something multiple times in a textbox. For example if you use this code and replace richtextbox with messagebox, it will keep displaying the text until the loop ends. I want to display the text from textBox1 into richTextBox1, and then have the program hit enter, and then type it out again in the richtextbox. It's kind of confusing sorry, but if you have any questions just comment them and i'll be more clear. This is my code:
private void button1_Click(object sender, EventArgs e)
{
Clipboard.SetText(textBox1.Text);
int text = 0;
int end = int.Parse(textBox2.Text);
while (text<=end)
{
richTextBox1.Text=(Clipboard.GetText());
text++;
}
Thanks in advance!
In your code you have:
richTextBox1.Text=(Clipboard.GetText());
The reason that your code is not working is because in every loop, you are setting the text to whatever is on the clipboard, so at the end of the loop it will only have it in there once. You need to 'append' or add onto the end of the text so it will have it multiple times:
richTextBox1.Text += richTextBox1.Text + (Clipboard.GetText());
Or:
richTextBox1.Text += (Clipboard.GetText());
This will add the clipboard text onto the end of the RichTextBox, so you will have the same text multiple times, but all on the same line. If you want to make the text appear on multiple lines, you have to add a new line after appending the text:
richTextBox1.Text += (Clipboard.GetText())+"\r\n";
Or:
richTextBox1.Text += (Clipboard.GetText())+Enviroment.NewLine;
Hope this Helps!
Use Timer instead of using loop and keep its interval time like for 2 second. and on button click start timer and declare end as class variable , when condition is met for "end" variable , stop timer.
private void button1_Click(object sender, EventArgs e)
{
end = int.Parse( textBox2.Text);
timer1.Start();
}
private int end = 0;
private int start = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (start == end)
{
timer1.Stop();
}
else
{
start++;
textBox1.Text = start.ToString();
}
}

Events and Buttons

I want to get the text of the button whenever I click on it.
The algorithm that I made is where i have a function that is a loop that creates a number of buttons and assigns numbers:
void ListAllPage()
{
if (pageMax < 50)
{
//if page max less than 50
for (int i = 0; i < pageMax; i++)
{
Button newBtn = new Button();
newBtn.Text = i.ToString();
newBtn.Width = 50;
newBtn.Click += page_Clicked;
pageCell.Controls.Add(newBtn);
}
}
}
Now buttons will appear on the screen, their events will be triggered and the function page_Click; will be executed:
public void page_Clicked(object sender, EventArgs e)
{
//inside this function I want to obtain the button number that was clicked by the user. How do I do that?
}
Take note, I must all the functions that I described here,...
My thinking is to feed all the buttons that i created inside the loop to a dictionary..
Dictionary.. it will take variables like this btndic.Add(Button b=new Button,b.text);
But the issue is how to retrieve the buttons,,,
if there is a better way, i would like to hear about it...
instead of using the Click Event -> Use the Command Event: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.oncommand.aspx then you can distinguish which button has been clicked
You just need to cast the sender object to a Button, or more generally, a Control:
public void page_Clicked(object sender, EventArgs e)
{
Control c = sender as Control;
MessageBox.Show("Clicked on " + c.Text);
}
Also, it might be more appropriate to use the Tag property to store your custom information (number). In that case, Text property can be anything you like.
Try this way
public void page_Clicked(object sender, EventArgs e)
{
Button btn=(Button)sender;
}
in your ListAllPage method assign Tag to each button:
newBtn.Tag = i;
In your handler you can obtain button instance from sender:
var clickedButton = (Button)sender;
int pageIndex = (int)clickedButton.Tag;

Disabling Timer .. why I can't?

When I use System.Windows.Forms.Timer class and finish using it then I can't disable it.. it ticks even if I set its property Enabled to false. What is wrong with the code? here is an example:
int counter = 0;
private void timer1_Tick(object sender, EventArgs e) {
MessageBox.Show("Hello");
counter++;
if (counter == 10){
timer1.Enabled = false;
}
}
This is a subtle bug that's induced by the MessageBox.Show() call. MessageBox pumps a message loop to keep the UI alive. Which allows the Tick event handler to run again, even though it is already active from the previous tick. The counter variable doesn't get incremented until you click the OK button. As a result, the screen fills with message boxes and that won't stop until you click the OK button ten times.
You need to increment the counter before showing the message box. Fix:
int counter = 0;
private void timer1_Tick(object sender, EventArgs e) {
counter++;
if (counter > 10) timer1.Enabled = false;
else MessageBox.Show("Hello");
}
This kind of problem is also the reason that DoEvents() got such a bad reputation. It is pretty difficult to write code that can properly deal with the re-entrancy induced by the message loop. You need to keep boolean flags around that indicate that code is already active. Which is another way to solve your problem:
int counter = 0;
bool showingBox = false;
private void timer1_Tick(object sender, EventArgs e) {
if (showingBox) return;
showingBox = true;
try {
MessageBox.Show("Hello");
counter++;
if (counter == 10) timer1.Enabled = false;
}
finally {
showingBox = false;
}
}
You now get only one message box at a time, probably what you are really looking for.
I should mention that this re-entrancy problem is pretty specific to timers. A dialog takes counter-measures to avoid re-entrancy problems, it disables all the windows in the application. That ensures that the user cannot do things like closing the main window or clicking a button that brings up the dialog again. Both rather disastrous mishaps. That takes care of most of the 'unexpected' Windows notifications, basically any of the messages that are generated by the user. The edge case is a timer (WM_TIMER is not disabled) whose event handler has a UI effect.
It is because the MessageBox.Show blocks until the user presses OK.
The code below the MessageBox will not execute until after 10 OK buttons are pressed.
But the timer continues to fire even if the execution is blocked.
Try this code
int counter = 0;
private void timer1_Tick(object sender, EventArgs e) {
counter++;
if (counter == 10){
timer1.Enabled = false;
}
MessageBox.Show("Hello");
}
(just moved the MessageBox)
What about timer1.Stop()? I am not too familiar with this class, but looked it up quickly: Timer Class
try this:
int counter = 0;
private void timer1_Tick(object sender, EventArgs e) {
MessageBox.Show("Hello");
counter++;
if (counter == 10){
timer1.Stop();
timer1.Dispose();
timer1 = null;
}
}
It is also working for me. I placed the timer in the form, on the button click, I am calling timer1.start() and I put the following code in the tick event and its working.
int i = 0;
private void timer1_Tick(object sender, EventArgs e)
{
i++;
this.Text = i.ToString();
if (i == 10)
{
timer1.Enabled = false;
}
}
You need to call Stop.
int i = 0;
private void timer1_Tick(object sender, EventArgs e)
{
i++;
if (i == 10)
{
timer1.Stop();
}
}
I'm pretty sure the MessageBox is the culprit here. Maybe if you use a short execution interval for the timer handler then this could potentially cause your code to function undesirably, if executions are overlapping.
The problem would be, in this case, that the handler executes and displays the MessageBox which in turn halts execution of the current scope until the the prompt is acknowledged by the user, meanwhile the handler has started again, showing another prompt, and another, and so on. At this point, we have multiple MessageBoxes waiting for input, yet counter hasn't even been incremented once. When we click 'OK' on the prompt, counter increments as desired, but at this point has a value of 1, rather than a value representing the number of prompts shown. This means yet another prompt will be displayed if more time elapses, until the user clicks 'OK' on at least 10 prompts.
You could try inhibiting execution if the process is already under way in order to prevent concurrent runs:
private readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
int counter = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (Locker.TryEnterWriteLock(0))
{
try
{
MessageBox.Show("Hello");
Counter++;
if (Counter == 10)
{
Timer.Enabled = false;
}
}
catch { }
finally
{
Locker.ExitWriteLock();
}
}
}

Categories