views:

79

answers:

4

My problem is that I can only seem to click the button once, if I click multiple times it's like it's dead. Doesn't do anything. So if I click it once it sets the text to "Works". How come it doesn't keep alternating between values when I click many times?

I have the following C# code (I know I am using too many namespaces, but please disregard that);

using System;
using System.Collections.Generic;
using System.Data;
using System.Web.Security;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
{
    Label1.Text = "Click to test";
}

protected void Click(object sender, EventArgs e)
{

    if (Label1.Text == "Works")
    {
        Label1.Text = "Try again";
    }

    else
    {
        Label1.Text = "Works";
    }
}
}

And here is the ASPX code;

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
        </Triggers>
    </asp:UpdatePanel>
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Click" /> 

    </form>
</body>
</html>
+6  A: 

In your Page_Load you need to check IsPostBack If it is a postback you shouldn't set the control value.

protected void Page_Load(object sender, EventArgs e)
{ 
     if (!IsPostBack)
        Label1.Text = "Click to test";
}

Or in the case of an ajax update, it's IsAutoPostback (I think!)

Sophie88
For ajax update, it's Page.IsCallBack.
madatanic
Ahh, that helped. It works perfectly with "!IsPostBack", but I was trying to make it an async update. What am I missing to do that? I don't want a postback, I just want the updatepanel (which only contains the label) to be updated. Any suggestion?
cc0
@cc0: I think that your trigger needs to go before your ContentTemplate code.
Ardman
@Ardman: Good suggestion, I tried it. And I tried using "!Page.IsCallBack", to no avail. Any other suggestion?
cc0
@cc0: the other suggestion is to remove the EventName from the AsyncPostBackTrigger
Ardman
@Ardman: Tried that too, same result :( Any other tip?
cc0
@cc0: I have literally just created a new project and copied your code into it (except for the ASPX headings) and added Sophie88's suggestion and it works. May I suggest that you try and do the same?
Ardman
@Ardman: I did, and it does work if I use the !IsPostBack, but that is not an asynchronous update, right? That updates the whole page.
cc0
Would I need something like this in my C# code?protected void Page_Load(object sender, EventArgs e) { ScriptManager1.RegisterAsyncPostBackControl(Button1); }
cc0
@cc0: You are correct in the fact that it posts back the whole page.
Ardman
Hmm, then all the ajax stuff is wasted. Is there no way I can fix this to be a partial postback?
cc0
You're still getting partial rendering. Using IsPostBack is appropriate, even with an UpdatePanel. If you *just* want to test for async postbacks, try this: http://stackoverflow.com/questions/265686/how-can-you-tell-if-a-method-is-being-run-in-updatepanel-postback
Greg
Thanks so much! Solved :]
cc0
+1  A: 

Each time you load the page you are setting the Label1.Text to "Click to test" (Page_Load happens every time the page is displayed), then the click event is triggered and correctly sees that the label isn't set to "Works" and so sets it to "Works".

How to fix it, see Sophie88's answer.

Lazarus
+2  A: 

Why are you setting the Label1.Text in the page_load?

IN your markup, just set the Text property to "Click to test"

  <asp:Label ID="Label1" runat="server" Text="Click to test"></asp:Label>
Jack Marchetti
Good point, just to make a test.
cc0
+5  A: 

The solution is what Sophie88 suggested, but I wanted to add some additional detail to explain exactly what's happening.

User initially requests page: (IsPostBack is false )

  1. Aspx markup is parsed: Label1.Text is "Label"
  2. Page_Load fires, sets Label1.Text to "Click to test"

User clicks button the first time: (IsPostBack is true)

  1. Aspx markup is parsed: Label1.Text is "Label"
  2. ViewState is restored, Label1.Text becomes "Click to test"
  3. Page_Load runs, sets Label1.Text to "Click to test"
  4. Click method runs. Label1.Text == "Click to test", so Label1.Text set to "Works"

User clicks button second time: (IsPostBack is true)

  1. Aspx markup is parsed: Label1.Text is "Label"
  2. ViewState is restored, Label1.Text becomes "Works"
  3. Page_Load runs, sets Label1.Text to "Click to test"
  4. Click method runs. Label1.Text == "Click to test", so Label1.Text set to "Works"
Greg
Great explanation, thank you :]
cc0
+1 - Nice explanation of the page life cycle.
DaveB