Solved

It takes two clicks for a button to update my datagrid

Posted on 2004-09-09
10
279 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
ID: 12022772
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
ID: 12022806
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
ID: 12022838
"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
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 

Author Comment

by:yizchaknaveh
ID: 12022919
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
ID: 12023813
"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
 
LVL 8

Expert Comment

by:daffodils
ID: 12023843
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
ID: 12023869
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
ID: 12024265
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
ID: 12024306
"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
ID: 12029235
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

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses the ASP.NET AJAX ModalPopupExtender control. In this article we will show how to use the ModalPopupExtender control, how to display/show/call the ASP.NET AJAX ModalPopupExtender control from javascript, how to show/display/cal…
ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

829 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