Solved

It takes two clicks for a button to update my datagrid

Posted on 2004-09-09
10
271 Views
Last Modified: 2011-09-20
Hi,

I have a datagrid, consisting of both template and bound columns, that's manually populated at runtime.  I'm trying to add a button that'll sort and display the data in the grid.  The sort is done by re-submitting a query to SQL Server with "ORDER BY" appended.  

Afterwards, the "sort-by" column is stored in Session so that whenever Page_Load occurs, the data will be sorted correctly.

My problem is, it appears to take two clicks of the button to sort the data grid.  In other words, the Button1_Click function fails to sort the grid (so Page_Load has to do it).

I tried stepping through the code, and whenever I press the button, it first runs Page_Load, and only THEN Button1_Click (so that Session["sort-by"] is set correctly only the next time Page_Load is run).

Please help! (Code below)

private void Page_Load(object sender, System.EventArgs e)
{                  
  if (!IsPostBack)
  {
    GetSource2();
    BindGrid();
  }
  else
  {
    if(Session["sort-by"] != null)
    sqlSelectCommand1.CommandText += " ORDER BY " + Session["sort-by"];
    GetSource2();
    BindGrid();
   }
}

void BindGrid()
{
  // Set the data source and bind to the Data Grid control.
  DataGrid1.DataSource = equipmentDataSet;
  DataGrid1.DataBind();
}

void GetSource2()
{
  EquipmentSqlConn.Open();
  sqlDataAdapter1.Fill(equipmentDataSet);
  EquipmentSqlConn.Close();
}

private void Button1_Click(object sender, System.EventArgs e)
{
  Session["sort-by"] = " IP";
  sqlSelectCommand1.CommandText += " ORDER BY IP";
  GetSource2();
  BindGrid();
}


0
Comment
Question by:yizchaknaveh
  • 3
  • 3
  • 3
  • +1
10 Comments
 
LVL 8

Accepted Solution

by:
daffodils earned 167 total points
Comment Utility
To start with.. the sequence of events after a postback is that when you click on a button,
The Page_Load is the first function to be executed (if there is no validation)
Then Cached events (which cannot cause a postback like TextChanged etc, if defined)
And the Button Click (postback event) is the last event to be executed.

So your program logic has to be designed with the idea that Button Click will FOLLOW Page_Load.
>>>>it first runs Page_Load, and only THEN Button1_Click
So, this is normal behavior and not a bug.

Now, to sort your data by, lets say, column IP .. you don't need to query Database again.. that is a performance overload.. simply create a DataView to sort data (or even filter data, if you require).

private void Button1_Click(object sender, System.EventArgs e)
{
  DataView myDataView = equipmentDataSet.Tables["Equipment"].DefaultView;
  myDataView.Sort = "IP";
  DataGrid1.DataSource = myDataView;
  DataGrid1.DataBind();
}

Modify your "GetSource2()" function to include table name "Equipment".

void GetSource2()
{
  EquipmentSqlConn.Open();
  sqlDataAdapter1.Fill(equipmentDataSet, "Equipment");
  EquipmentSqlConn.Close();
}
0
 

Author Comment

by:yizchaknaveh
Comment Utility
Thanks for your response.

I  tried this method to begin with, but it didn't work, since apparently template columns (which my datagrid includes) aren't sorted correctly using simple DataViews.

Hence the code you gave me doesn't work.

That's why I decided to resubmit the query to the server (which works fine).  Is there any way to make my program work using this method? (or another?)

0
 
LVL 8

Expert Comment

by:boulder_bum
Comment Utility
"I  tried this method to begin with, but it didn't work, since apparently template columns (which my datagrid includes) aren't sorted correctly using simple DataViews."

A DataView sorts rows of a DataTable, which are then bound to your grid. It doesn't "sort" datagrid columns per se (if you're seeing something goofy, it's probably in how the binding is handled).

The DataView approach should work and is preferable, though it's typically done in the SortCommand event handler of the grid.

If interested, this may help:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebuiwebcontrolsdatagridclasssortcommandtopic.asp

0
 

Author Comment

by:yizchaknaveh
Comment Utility
Thanks for your comment, also.

Everything else works correctly (e.g., updates, views) so I don't know why the binding would be goofy.  But still, how can I check that?

From what I read on various sites, template columns can cause problems when you sort a datagrid (or rather its underlying representation).

I know about SortCommand, but for now I'm just trying to get the damned thing to work first :)
0
 
LVL 8

Assisted Solution

by:boulder_bum
boulder_bum earned 167 total points
Comment Utility
"I'm just trying to get the damned thing to work first"

I hear that, man!

"Everything else works correctly (e.g., updates, views) so I don't know why the binding would be goofy."

Well, here's the thing. When sorting, you basically just sort a data structure (DataSet or DataView or something) then you bind to the grid, which is essentially a blank slate. The first bind should be no different than the 500th.

Addditionally, you should be able to bind to a "sorted" DataSet just as easily as a sorted DataView, so it's puzzling that template columns would cause any sort of problem because they don't really know anything about the underlying DataSource (and certainly nothing about the differences between the original and freshly sorted DataSource).

For that reason, I'm wondering if there's something "goofy" with the way you're manipulating the DataView before the binding. Indeed, I've never seen the problem occur before and I bind to sorted DataViews all the time.

Out of curiosity, who made the claim about the template columns? I'd be interested to see the links if you still have them.

Regarding the current code, you can just yank this out unless ViewState is disabled on the grid.:

  else
  {
    if(Session["sort-by"] != null)
    sqlSelectCommand1.CommandText += " ORDER BY " + Session["sort-by"];
    GetSource2();
    BindGrid();
   }

I'm sure your problem revolves around the fact that you use both:

sqlSelectCommand1.CommandText += " ORDER BY " + Session["sort-by"];

in page load, and

sqlSelectCommand1.CommandText += " ORDER BY IP";

in the button event. This is because both lines will be executed on PostBack (when you click the button) and you'll end up with a SQL statement like:

"SELECT blah... ORDER BY IP ORDER BY IP"

because you += an "ORDER BY" clause twice.


0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 8

Expert Comment

by:daffodils
Comment Utility
Good point there boulder_bum... I didn't see that myself.
Yes that.. "else  {   if(Session["sort-by"] != null) }" block.. needs to go.

0
 
LVL 8

Expert Comment

by:daffodils
Comment Utility
Here's some sample code from MSDN using Sort on DataGrid (with Template Columns).. you CAN use them together.

.NET Samples - ASP.NET Server Control Reference
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpqstart/html/cpsmpnetsamples-aspnetservercontrolreference.asp

Click on the link for "DataGrid9".. here is the source code for it...
http://samples.gotdotnet.com/quickstart/util/srcview.aspx?path=%2fquickstart%2faspplus%2fsamples%2fwebforms%2fdata%2fdatagrid9.src
0
 
LVL 10

Assisted Solution

by:jnhorst
jnhorst earned 166 total points
Comment Utility
You should take the code that queries the database and fills the datatable *outside* of your if (!Page.IsPostBack) {} block.  Keep the DataBind on the grid inside that block.  Here is the thinking:

When you first load the page, you get the data and then you bind the grid because it is not a postback.  Since you are applying a filter, when you fire the postback to filter and/or sort, you want to make sure you are getting the data again.  This is why you put the Fill() call before the if (!Page.IsPostBack) condition.  When your control fires the postback, as has been mentioned, Page_Load fires first.  You want to get your data even though it is a postback.  Then the event for the control that caused the postback (like the click event on a button) will fire.  In this event you want to reapply your filter and sort expressions to the DataView (or the DefaultView of the datatable) and call DataBind() on the grid.

If you have paging enabled, you want to do this as well in the PageIndexChanged event after setting the CurrentPageIndex property of the grid.

Get rid of the block of code in else{} in Page_Load.  All you need to do is set the Sort property to the column in the data table you want to sort by.  Don't worry about resending the query with "Order By".  With the DataGrid, you can set AllowSorting property to true and then code up a SortCommand routine.  When you click on the header for a column, a postback will fire.  Your Page_Load event will get your data.  Then the SortCommand routine will fire and you will set the SortExpression.

The key is to get your data into the datatable both on postbacks and non-postbacks.

John
0
 
LVL 8

Expert Comment

by:boulder_bum
Comment Utility
"Good point there boulder_bum... I didn't see that myself.
Yes that.. "else  {   if(Session["sort-by"] != null) }" block.. needs to go."

Did that clear things up? I'm crossing my fingers for ya.
0
 

Author Comment

by:yizchaknaveh
Comment Utility
Thank you kindly to everyone who responded!  

After attempting these solutions with no success, I realized, as boulder_bum suggested, that something else in my code was probably screwy (I tried to sort a datagrid on a fresh ASP.NET project and it worked fine).  So I just started with sample code from MSDN and gradually moved parts of my code to the new project.  Now I can sort the datagrid is sorted in just one click. ;)

I have a much better idea now of what goes on behind the scenes.  Thanks for clearing up my misapprehensions about the ASP.NET event model!

I've split the points between all of you.  I hope that's OK -- it's my first question on experts-exchange, and I'm not familiar with the rules yet...
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
VBSCRIPT in Page Load C# ASP.NET 6 52
How to perform calculation 2 24
ASP.NET e-commerce website 4 26
Problem to go to Web page 2 46
Sometimes in DotNetNuke module development you want to swap controls within the same module definition.  In doing this DNN (somewhat annoyingly) swaps the Skin and Container definitions to the default admin selections.  To get around this you need t…
IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now