【问题标题】:Counter won't increment more than once onclick计数器在点击时不会增加一次以上
【发布时间】:2014-07-28 06:45:05
【问题描述】:

我有一个计数器,onclick 应该递增 1,它会在点击时执行此操作,但如果我再次点击该按钮,它将不会再次递增。相反,它会停留在 1。如果多次单击按钮,我怎样才能让它上升?

 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();

            }
        }

【问题讨论】:

  • int counter移到方法外。
  • @Sayse 我怀疑这将是 the 解决方案。实例成员和静态成员之间仍然存在差异......
  • @AndreasNiedermair - 这与它有什么关系? - 另外,您可能希望阅读此内容 - Variable and Method Scope in Microsoft .NET
  • @Sayse 再次阅读了这个问题:“但如果我再次单击该按钮,它就不会再次增加。” ...所以你需要一个线程独立值并以某种方式将后续点击附加到正确的 instance(例如 ThreadStatic,它在 web 上下文中不起作用)
  • @AndreasNiedermair - 我们不知道 OP 正在构建什么样的应用程序。他们的术语可能被解释为表明它是一个网络应用程序,但这绝不是肯定的(如果是,那么Session 是解决问题的明显位置)

标签: c# asp.net


【解决方案1】:

您需要在方法之外创建counter例如类中的field,而不是局部变量:

private int counter = 0;
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
  if (mathAnswerTextBox.Text == answer.ToString())
    {
        answerStatus.Text = "Correct!";
  ...

由于这是一个 Web 应用程序,您可能希望将计数器存储在 session 中,例如:

内部Page_Load

if(!IsPostback)
{
   Session["AttemptCount"] = 0
}

然后在里面

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; 

【讨论】:

  • @Sayse 我怀疑这将是 the 解决方案。实例成员和静态成员之间仍然存在差异。并且静态存在线程上下文(以及后续线程上下文......)的问题
  • @AndreasNiedermair,OP 没有提到这段代码的上下文。如果 OP 使用的是 ASP.NET(正如 Damien 所指出的那样),那么他可以使用任何状态管理(最好是会话)(OR)来管理它,如果他使用 Winform 则可能声明一个静态变量。
  • 您宁愿描述会话的“缺点”:它适用于浏览器实例的每个选项卡,您无法区分它们 - 因此具有多个选项卡的用户将更新该值横向 - 一个选项卡执行 POST 而另一个执行 GETs 将导致每个 GET 请求重置会话值...
【解决方案2】:

就目前而言,counter 是一个局部变量(如下面的代码),因此每次单击按钮时,它都会初始化为 0,因此每次都会得到 1,因为它会增加一次。

 protected void submitAnswerButton_Click(object sender, EventArgs e)
    {
  int counter = 0;

【讨论】:

    【解决方案3】:

    您需要将值存储在更全局的上下文中,例如 ViewStateSession 甚至可能是 HiddenField 来存储值。

    结论:Web 是无状态的,因此您需要一个状态管理器。

    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
    }
    

    无论如何 - 这仅在您无状态的网络环境中有效。

    如果您在 webform/wpf-context 中,您宁愿选择简单的static,或实例变量,或...(无论适合您当前的需求、架构...)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-11
      • 2019-05-12
      • 1970-01-01
      • 2022-10-20
      • 1970-01-01
      • 2012-10-30
      相关资源
      最近更新 更多