GridView - two clicks needed to enter in-place editing

  • Thread starter Thread starter Hrvoje Vrbanc
  • Start date Start date
H

Hrvoje Vrbanc

Hello all,

I've encountered a very strange problem: I have a GridView control on an
..aspx page that displays data correctly (in any case; with autogenerated
columns or with using item templates).

I added "Edit, Update, Cancel" command button to the GridView but when I
click on "Edit" nothing happens. I have to click the same button again and
only then the row displays EditItem template.

The same happens when I press, e.g. "Cancel" button - it takes two clicks to
enter normal GridView display mode.

I tried it on two machines and on both VS development server and full IIS
and it's always the same. It's very strange.

Is it some sort of a trivial problem and I'm somehow missing something
obvious?

Thank you in advance,
Hrvoje
 
Have you written any custom code for your GridView? This behavior is
usually associated with calling DataBind incorrectly and/or turning off
ViewState for the control.

Try another test, but this time don't change any properties of the GridView
(not even its looks) and just enable Edit, Update, & Cancel via the smart
tag. See if this works properly.
 
Thanks!
However, I have tried a "basic set up" and had the same problems.
I have inserted a GridView, changed nothing and added just two events in the
codebehind (beside the code necessary to create, fill and bind the dataset):

Protected Sub GridView1_RowCancelingEdit(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles
GridView1.RowCancelingEdit

GridView1.EditIndex = -1

End Sub

Protected Sub GridView1_RowEditing(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewEditEventArgs) Handles
GridView1.RowEditing

GridView1.EditIndex = e.NewEditIndex

End Sub



Maybe that's because there's no real code beside index determination?



Thank you,

Hrvoje
 
Yes, as suspected the problem is in your code, and is a DataBind call
problem.

You didn't provide your complete code that fills and binds (and is part of
the problem), but I can explain what to do anyway.

You only want to be calling the Databind method once per page call and it
must be done at the "right" time. I suspect your call is in your Page_Load
event and *not* wrapped in a test for a postback, as it should be. Your
filling and binding code should look something like this:

Sub Page_Load()
'code to connect and fill
If Not IsPostBack Then
'Databinding should be the last thing you do to your GridView
'Since we know this code only runs the first time your page is being
loaded,
'we know that it's not being loaded as a result of any kind of
GridView user
'manipulation (like a sort, select, edit, or page change)
GridView.DataBind
End If
End Sub

When your page is loading for the first time, your event handlers for
selecting, sorting, editing and paging are not going to be called because
how could a user be doing such things if they haven't even received the page
for the first time?

But, what if the page is loading NOT for the first time? Then, we have to
ask *why* would the page be loading for a subsequent time? The answer is
that the user initiated this subsequent page call by sorting, selecting,
editing, or paging the GridVeiw, in which case, Page_Load will NOT be the
last page event to fire in these cases. If you had been binding your
GridView in Page_Load for every page call (as I suspect you have been
doing), then you are binding your GridView before your code is done working
with it (sure Page_Load is done, but now we've got to execute the sort,
select, edit, paging event handlers).

So, in PostBack situations, we don't want to bind to the GridView yet, we
want to do it when we are done configuring the GridView for this current
page display. This means that in EACH of your GridView event handlers, the
LAST command should be GridVeiw.DataBind(). For example:

Sub GridView1_RowCancelingEdit(ByVal . . .) Handles
GridView1.RowCancelingEdit
GridView1.EditIndex = -1
GridView1.DataBind()
End Sub

Sub GridView1_RowEditing(ByVal . . .) Handles GridView1.RowEditing
GridView1.EditIndex = e.NewEditIndex
GridView1.DataBind()
End Sub

This way we know the following:
1. The first time the page loads, the LAST thing done to the GridView
is DataBind in Page_Load
2. Any subsequent time the page loads, the LAST thing done to the
GridView is DataBind is the particular event handler that triggered the page
call in the first place.

Now, as an aside... You do know that you can fill, bind, populate, select,
sort, edit, and page a GridView without a single line of code, right?

Good luck!

-Scott
 
Thank you!
In fact, my DataGrid was populated on click of the button that executed a
query corresponding to the search string.

But, as soon as I added a call to the Binding() sub to those two evets,
things started working prefectly.
Thank you once more!

Regards,
Hrvoje
 
Glad to help. And, by the way, even though you are using the value from a
control as a parameter to a query, you can still do all of this with no code
in VS 2005. In the DataSet Wizard, you have the choice to make a
parameterized query that gets its value from an existing control.

Good luck!

-Scott
 
Thank you very much.
I never tried using wizards too much in ASP.NET 2.0 because I like to have
as much as possible of my code in the codebehind (I don't like having e.g.
SQL code in an .aspx file). Or, better said, I never got into wizard offered
possibilities deep enough and continued to work as much as possible as in
ASP.NET 1.1 (I've done the vast majority of my work in 1.1 because MS CMS
2002 that I use for my sites requires 1.1).

Also, I always tend to write as much code as possible in separate classes
that I instantiate from the codebehind and almost always use stored
procedures located on an SQL Server. In fact, I'm not familiar with what I
gain if I do the things the different way.

Hrvoje
 
Hi Hrvoje

See my comments inline.....

Hrvoje Vrbanc said:
Thank you very much.
I never tried using wizards too much in ASP.NET 2.0 because I like to have
as much as possible of my code in the codebehind (I don't like having e.g.
SQL code in an .aspx file).

Because of the new declarative way that ASP .NET 2.0 controls
compile/render, there's much less actual code to even worry about now.
Or, better said, I never got into wizard offered possibilities deep enough
and continued to work as much as possible as in ASP.NET 1.1 (I've done the
vast majority of my work in 1.1 because MS CMS 2002 that I use for my
sites requires 1.1).

Also, I always tend to write as much code as possible in separate classes
that I instantiate from the codebehind and almost always use stored
procedures located on an SQL Server. In fact, I'm not familiar with what I
gain if I do the things the different way.

In ASP .NET 2.0 the controls can be configured to use stored procedures
(with parameters based on controls, querystrings, etc.) without any vb code
at design-time (zero code in the code-behind). What you gain is not having
to worry about coding Databinding, Editing, Updating, Sorting, Deleting and
Paging! :)

-Scott
 
Hi, I was wondering if you could help me, I have a gridview that i populated using the wizzard, it displays the first,last name and contact number of people in the person table within the database. it allows for edit, update, cancel. then i have a search facility on first or lastname that takes the name entered in the textbox and calls stored procedures in the database depending on the selected index of the dropdown(Search by: containing first, last name). If you haven't searched for anything the edit update works perfectly, as soon as the grid gets populated with the search result and i click edit, the grid disappears. Can you tell me what the problem is? I have tried puting the gridview.databind() in all places possible but it just dont seem to want to work. any advice will be deeply appresiated...
 
Back
Top