tags:

views:

2200

answers:

6

I got a web application, the problem is that the text in the label will not update on the first click, I need to click the button twice, I debugged to code, and I found out that the label does not recive the data until after the second click,

Here is my code:

System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
System.Data.SqlClient.SqlConnection connection;
string CommandText;
string game;
string modtype;
bool filter;
protected void Page_Load(object sender, EventArgs e)
{

    labDownloadList.Text = null;

    //Session variables:
    if (Session["Game"] != null)
    {
        game = Convert.ToString(Session["Game"]);
    }
    if (Session["ModType"] != null)
    {
        modtype = Convert.ToString(Session["ModType"]);
    }
    if (Session["FilterBool"] != null)
    {
        filter = Convert.ToBoolean(Session["FilterBool"]);
    }
    string ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\inetpub\\wwwroot\\stian\\App_Data\\Database.mdf;Integrated Security=True;User Instance=True";
    connection = new System.Data.SqlClient.SqlConnection(ConnectionString);
    System.Data.SqlClient.SqlDataReader reader;
    command = connection.CreateCommand();
    connection.Open();
    CommandText = "SELECT * FROM Command";
    if (filter)
    {
        CommandText = "SELECT * FROM Command WHERE Game='" + game + "' AND Type='" + modtype + "'";
    }
    command.CommandText = CommandText;
    reader = command.ExecuteReader();
    labDownloadList.Text = "";
    while (reader.Read())
    {
        string game = reader.GetString(1);
        string author = reader.GetString(2);
        string downloadlink = reader.GetString(3);
        string size = reader.GetString(4);
        string description = reader.GetString(5);
        string version = reader.GetString(6);
        string screenshotlink = reader.GetString(7);
        Int64 AmountDownloaded = reader.GetInt64(8);

        labDownloadList.Text += "Game: " + game + "<br>";
        labDownloadList.Text += "Author: " + author + "<br>";
        labDownloadList.Text += "Size: " + size + "<br>";
        labDownloadList.Text += "Description: " + description + "<br>";
        labDownloadList.Text += "Version: " + version + "<br>";
        labDownloadList.Text += "<img src='" + screenshotlink + " /><br>";
        labDownloadList.Text += "Downloaded: " + AmountDownloaded + " times<br><hr>";
        labDownloadList.Text += "<a href='" + downloadlink + "'>Download</a><br>";
    }
}

protected void Page_UnLoad(object sender, EventArgs e)
{
    Session["Game"] = game;
    Session["ModType"] = modtype;
    Session["FilterBool"] = filter;
    connection.Close();
}

protected void btnFilter_Click(object sender, EventArgs e)
{
    game = lstGames.SelectedValue;
    modtype = lstTypeMod.SelectedValue;
    filter = true;
}
+1  A: 

I'm not seeing the typical

if (!Page.IsPostBack)
{
   ...
}

in your Page_Load method, which means that your datbinding will occur every time the page is loaded, most likely causing your issue. I'd suggest adding that to the code and see if it resolves the issue.

Dillie-O
+3  A: 

The button click event handlers happen AFTER Page_Load. Try using Page_LoadComplete instead.

So, in your code, once the button is clicked, the page_load event fires and sets the data, then the btnClick event fires and changes the data. But, the data was already bound in it's old form. That's why it takes 2 clicks for it to work.

If you put the same page_load code into the page_loadcomplete event instead, it will happen after the btnClick event. That should produce the desired result.

EndangeredMassa
+4  A: 

Microsoft's overview of the Page Life Cycle may be helpful in understanding the flow (and resolving your issue).

Jonathan S.
That is such a great article, I'm constantly referring people to it
Slace
A: 

Thank you all for the answers, I will try the solutions tommorow.

+1  A: 

To be very clear. The button click event happens after the Page_Load event meaning that the filtering does not get applied on the first postback. It has been updated on the second postback and you see the filtering. The simplest change to get your code to work is to move all the code in your Page_Load event into OnPreRender so the reload happens after the button click event.

A cleaner solution however is probably to move it into a LoadData function and call that on PageLoad when it is not a postback and also call it on the button click event after updating your filters. That will prevent a call to the database on any postback page cycles that do not need to reload the data:

 
protected void Page_Load(object sender, EventArgs e)
{    
    if (!Page.IsPostBack)
        {   
             LoadData()
        }
}

private void LoadData()
{
    labDownloadList.Text = null;
    //Session variables:    
    if (Session["Game"] != null)
    ...
}

protected void btnFilter_Click(object sender, EventArgs e)
{    
    game = lstGames.SelectedValue;
    modtype = lstTypeMod.SelectedValue;
    filter = true;
    LoadData();
}
 

A last piece of quick advice for a budding ASP.Net developer is to thoroughly learn the page lifecycle. Knowing the sequence of events on a page is essential. Good Luck.

JackCorn
A: 

JackCom, the solution worked! Thank you. And I will study the page lifecycle. I must add, that I only have experience in software development, I have just started with web development this autumn.