I have a few buttons in my webpage and was trying to restrict the button clicks by having a countClick method to check the number of clicks the users have pressed. In my codes below, when users click on the first button, the second button will automatically be clicked for them. And if they were to choose the second button instead, the third button will be clicked for them automatically too and so on for the rest of the buttons. However in my case, they can only click once as one click accounts for 2 buttons to be clicked. So, when they have clicked once, i cannot allow them to click on the second time.
My problem is that my countClick method is not working. When i run my page, all my buttons can be selected and it does not restrict the user to only 1 button click.
Here is my .cs code:
protected void Button1_Click(object sender, EventArgs e)
{
Button1.Text = "Booked";
Button1.BackColor = System.Drawing.Color.Blue;
Button2.Text = "Booked";
Button2.BackColor = System.Drawing.Color.Blue;
countButtonClick();
}
protected void Button2_Click(object sender, EventArgs e)
{
Button2.Text = "Booked";
Button2.BackColor = System.Drawing.Color.Blue;
Button3.Text = "Booked";
Button3.BackColor = System.Drawing.Color.Blue;
countButtonClick();
}
protected void Button3_Click(object sender, EventArgs e)
{
Button3.Text = "Booked";
Button3.BackColor = System.Drawing.Color.Blue;
Button4.Text = "Booked";
Button4.BackColor = System.Drawing.Color.Blue;
countButtonClick();
}
protected void Button4_Click(object sender, EventArgs e)
{
Button4.Text = "Booked";
Button4.BackColor = System.Drawing.Color.Blue;
countButtonClick();
}
Here is my countClick method in .cs:
private void countButtonClick()
{
int counter = 0;
counter++;
if (counter >= 1)
{
Response.Write("You can only select 2 slots! " + DateTime.Now.ToString());
}
}
Store counter as a session variable.
Because you are declaring it inside your function, it is unique for that specific instance of that call to the function. Therefore it is reset to 0 each time.
private void countButtonClick()
{
int counter = 0;
if (!(Session["counter"])){
counter = (int)Session["counter"];
}
counter++;
Session["counter"] = counter;
if (counter >= 1)
{
Response.Write("You can only select 2 slots! " + DateTime.Now.ToString());
}
}
I would then also ensure the session value is lost when a refresh is made by adding the following to your Page Load method:
if (!(Page.IsPostBack)){
Session["counter"] = null;
}
I see two problems here:
First, counter needs to be a session variable, and second, you should probably call countClick() before modifying anything on the page, and making it return bool so you can tell if it succeeded or not.
private bool countClick()
{
if (Session["clicks"] == null)
{
Session["clicks"] = 1;
return true;
}
if (++((int)Session["clicks"]) > 1)
{
Response.Write("...");
return false;
}
return true;
}
protected void Button1_Click(object sender, EventArgs e)
{
if (countClick())
{
Button1.Text = "Booked";
Button1.BackColor = System.Drawing.Color.Blue;
Button2.Text = "Booked";
Button2.BackColor = System.Drawing.Color.Blue;
}
}
Your countButtonClick method uses counter as a locally scoped variable, by declaring it inside the method. This means every time the method is called, the counter will be created and initialized to 0. Additionally, the number of clicks won't be preserved across postbacks. Even if you move the counter declaration outside of countButtonClick, every time a button is clicked, the counter variable will be reset to 0, because of how the page lifecycle works. The way to resolve this is to store the counter in some fashion, such as session or view state.
private int counter = 0;
protected void Page_Load()
{
if(!Page.IsPostback)
{
ViewState["MyClickCounter"] = 0;
}
else
{
counter = (int)ViewState["MyClickCounter"];
}
}
private void countButtonClick()
{
counter++;
ViewState["MyClickCounter"] = counter;
if (counter >= 1)
{
Response.Write("You can only select 2 slots! " + DateTime.Now.ToString());
}
}
You also may want to add a reset method, depending on what your page needs to do.
Related
I'm messing around trying to make a tictactoe game and am wondering how to use this method I created to alter the text of a button.
private void Click()
{
if (player1 == true)
{
player1 = false;
player2 = true;
this.Text = "X";
}
if (player2 == true)
{
player1 = true;
player2 = false;
this.Text = "O";
}
}
private void button1_Click(object sender, EventArgs e)
{
Click();
}
So I want to be able to change the text of the buttons, I found out that this relates to the actual form. I couldn't find any ways to assign the text to different buttons only if you are specific. Cheeeeers.
"this" is your form. You need to assign your text to button.Text.
Since your are writing a tic-tac-toe you could use the same event for all buttons :)
private void button1_Click(object sender, EventArgs e)
{
var button = (Button) sender;
button.Text = "X";
}
You could add the button1 as a parameter to your click event, like:
private void Click(Control control) {
if (!string.IsNullOrEmpty(control.Text)) {
// invalid button clicked (has already x or o)
return;
}
control.Text = player1 ? 'X' : 'O';
player1 = !player1;
player2 = !player2;
}
and then use the click event as:
private void GeneralButtonHandler(object sender, EventArgs e)
{
Click(sender as Control);
}
after which you could attach all buttons to this GeneralButtonHandler
and if you need more ideas for the game, you could find a javascript implementation here
Am new to C# and i need your help on this, I want to display one character at a time in a textbox this is my code
private void timer1_Tick(object sender, EventArgs e)
{
int i = 0; //why does this don't increment when it ticks again?
string str = "Herman Lukindo";
textBox1.Text += str[i];
i++;
}
private void button1_Click(object sender, EventArgs e)
{
if(timer1.Enabled == false )
{
timer1.Enabled = true;
button1.Text = "Stop";
}
else if(timer1 .Enabled == true )
{
timer1.Enabled = false;
button1.Text = "Start";
}
}
why does this don't increment when it ticks again?
Because your variable i is local to your event. You need to define it at class level.
int i = 0; //at class level
private void timer1_Tick(object sender, EventArgs e)
{
string str = "Herman Lukindo";
textBox1.Text += str[i];
i++;
}
On exit of your event, variable i becomes out of scope and looses its value. On the next event it is considered a new local variable with the initialized value of 0.
Next, you should also look for cross threaded exception. Since your TextBox is not getting updated on the UI thread.
The issue with you code is that you are assigning i = 0 with every tick, so it will always be 0 everytime it is used. I would suggest using a class level variable for this.
However, using a variable at class level means you are going to need to reset to 0 at some point, probably each time you start the timer.
A further point is that you are going to want to validate the tick event to ensure you don't try to access an index that doesn't exist (IndexOutOfRangeException). For this I would recommend automatically stopping the timer once the last letter has been printed.
With all that in mind, here is my suggested code:
int i = 0;// Create i at class level to ensure the value is maintain between tick events.
private void timer1_Tick(object sender, EventArgs e)
{
string str = "Herman Lukindo";
// Check to see if we have reached the end of the string. If so, then stop the timer.
if(i >= str.Length)
{
StopTimer();
}
else
{
textBox1.Text += str[i];
i++;
}
}
private void button1_Click(object sender, EventArgs e)
{
// If timer is running then stop it.
if(timer1.Enabled)
{
StopTimer();
}
// Otherwise (timer not running) start it.
else
{
StartTimer();
}
}
void StartTimer()
{
i = 0;// Reset counter to 0 ready for next time.
textBox1.Text = "";// Reset the text box ready for next time.
timer1.Enabled = true;
button1.Text = "Stop";
}
void StopTimer()
{
timer1.Enabled = false;
button1.Text = "Start";
}
I have a counter that onclick should increment 1 and it does that on click, but if I click the button again, it won't increment again. Instead it will be stuck at 1. How can I make it go up if the button is clicked more than once?
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
int counter = 0;
if (mathAnswerTextBox.Text == answer.ToString())
{
answerStatus.Text = "Correct!";
}
else if (mathAnswerTextBox.Text != answer.ToString())
{
answerStatus.Text = "Incorrect";
counter++;
if (counter == 1)
{
incorrectStrikes.Text = counter.ToString();
}
else if (counter == 2)
{
incorrectStrikes.Text = counter.ToString();
}
else if (counter == 3)
{
incorrectStrikes.Text = counter.ToString();
}
}
You would need to make counter outside of the method, such as a field in the class, not a local variable:
private int counter = 0;
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
if (mathAnswerTextBox.Text == answer.ToString())
{
answerStatus.Text = "Correct!";
...
Since this is a web application you'd probably want to store the counter in the session, something like:
Inside Page_Load:
if(!IsPostback)
{
Session["AttemptCount"] = 0
}
And then inside
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
int counter = (int)Session["AttemptCount"];
if (mathAnswerTextBox.Text == answer.ToString())
{
answerStatus.Text = "Correct!";
...
//Make sure you include this on all paths through this method that
//affect counter
Session["AttemptCount"] = counter;
As it stands you counter is a local variable (as in below code) and so every time you click button it will get initialized to 0 and hence you get 1 every time cause it's getting incremented once.
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
int counter = 0;
You'll need to store the value in a more global context, eg ViewState or Session or maybe even a HiddenField for storage of the value.
Conclusio: Web is stateless so you'd need a state-manager.
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
var counter = this.ViewState["foo"] as int; // read it from the ViewState from the previous request, or set it to default(int) = 0 with as
// ... do your routine
this.ViewState["foo] = counter; // write it back to store it for the next request
}
Anyway - this is just valid in a web-context where you are stateless.
If you were in a webform/wpf-context you would rather go for a simple static, or instance-variable, or ... (whatever suits your current need, architecture, ...)
i'm new to C# (and programming at all) and i'm trying to write an 'XO' game along with ASP.NET
i'm getting a problem after the first player clicks a button.
turns doesn't switch and any click after the 1st does nothing. what is wrong with my code ?
public partial class GamePage : System.Web.UI.Page
{
Player player1 = new Player();
Player player2 = new Player();
int turn;
protected void Page_Load(object sender, EventArgs e)
{
this.turn = 0;
if (!IsPostBack)
{
Label1.Visible = true;
}
if (turn == 0)
{
Label1.Text = (Session["player1"] as Player).getname();
}
else
{
Label1.Text = (Session["player2"] as Player).getname();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["p1"] = player1;
Session["p2"] = player2;
player1.setsymbol("X");
player2.setsymbol("O");
if (Button1.Text == "")
{
if (turn == 0)
{
Button1.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button1.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button2_Click(object sender, EventArgs e)
{
if (Button2.Text == "")
{
if (turn == 0)
{
Button2.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button2.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button3_Click(object sender, EventArgs e)
{
if (Button3.Text == "")
{
if (turn == 0)
{
Button3.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button3.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
// this is an example - i have the same lines from button1 to 9
Everytime page renders, you set turn to 0 in Page_Load. Because Page_Load is executed upon every page load, you won't get any other value and this is probably the major issue here.
To properly support the lifetime of such variables that should keep value upon consecutive requests, wrap them in simple property:
public int turn
{
get
{
if ( Session["turn"] != null )
return (int)Session["turn"];
return 0; // default value if not set before
}
set
{
Session["turn"] = value;
}
}
This way everytime you refer to turn in your code, setting it to 0 or 1 or comparing the value to 0 or 1, you will refer to the same value, possibly stored during previous request(s).
this.turn=0; should be executed only when IsPostBack is false. Move this line inside if in your Page_Load.
I am having problems getting my page to maintain state. View state is enabled by default but everytime I click a button it resets the form. This is the code I have
protected void Page_Load(object sender, EventArgs e)
{
Levels loadGame = new Levels(currentGame);
int [] gameNums = loadGame.getLevelNums();
int inc = 1;
foreach(int i in gameNums){
if (i != 0)
{
TextBox tb = (TextBox)FindControl("TextBox" + inc);
tb.Text = i.ToString();
tb.Enabled = false;
}
else {
//leave blank and move to next box
}
inc++;
}
This is the initial load
protected void NormalButton_Click(object sender, EventArgs e)
{
clearBoxes();//clear boxes first
setCurrentGame("normal");//setting to normal returns normal answers
Levels loadGame = new Levels(returnCurrentGame());
int[] gameNums = loadGame.getLevelNums();
int inc = 1;
foreach (int i in gameNums)
{
if (i != 0)
{
TextBox tb = (TextBox)FindControl("TextBox" + inc);
tb.Text = i.ToString();
tb.Enabled = false;
}
else
{
//leave blank and move to next box
}
inc++;
}
}
Clicking this button changes the numbers in different boxes.
protected void Button1_Click(object sender, EventArgs e)
{
}
Then I have this empty button but everytime I click it, it resets the form even though I havent set it to do anything yet. I would like the boxes to stay the same and I would also like to keep the objects alive. I'm not sure what I'm missing but please point me in the right direction. Thanks in advance
The Page_Load event occurs every time the page is loaded, including event-driven postbacks (button clicks, etc).
It looks like initialization code is in your Page_Load, so when you click the button it runs again.
There are two options:
Put everything that you want to happen only on the FIRST load in a n if statement:
Move your initialization to Page_Init.
Code sample for the first option:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack) // Teis is the key line for avoiding the problem
{
Levels loadGame = new Levels(currentGame);
int [] gameNums = loadGame.getLevelNums();
int inc = 1;
foreach(int i in gameNums){
if (i != 0)
{
TextBox tb = (TextBox)FindControl("TextBox" + inc);
tb.Text = i.ToString();
tb.Enabled = false;
}
else {
//leave blank and move to next box
}
inc++;
}
}
}
Also, recommended reading: The ASP.NET Page Lifecycle