// Note: GetDataTable() returns a non-null DataTable object.
// Also the DataTable has more than 1 row
// (i.e. everything is fine with the datatable)
2- the GridView has a Delete Command Field.
3- on tracing I've noticed my RowDeleting event gets fired twice! (also I used a static counter to see how many times the event gets fired when clicking on the GridView delete button, which was also confirmed it that it's counting 2 per each click).
ok, just in case anyone else is facing events getting triggered twice (for any reason), and getting the infamous "Deleted row information cannot be accessed through the row." exception, I wrote a method that prevents the duplication (unorthodox but it works).
just call it at the beginning of your RowDeleting event handling method. Example:
if (!Ok2Delete(2)) return; // parameter of 2 if event is firing twice
// 3 if trice, etc...
However, now that the event triggering twice is solve. But the funny part is (for me) the event turned out to be inconsistance in its behaviour (i.e. fires randomly either twice or one time).
And if someone else also facing similiar inconsistance behaviour, I'd advice to do like what I'll hopefully do; which is letting the user select the rows and clicks on a button (outside the grid) to delete them instead of embeded delete button within each row.
finally I found a proper solution for it. The problem seems a known ASP.NET issue.
Anyway, I wrote this method that needs to be called at the begninning of the event handling method:
private bool Ok2Delete(int ri) // ri is the record index to be deleted
{
if (Session["ri"] == null ||
(!((ri == ((int)Session["ri"])) &&
(DateTime.Now.Subtract((DateTime)Session["ri_time_stamp"]).Seconds < 2))))
{
Session["ri"] = ri;
Session["ri_time_stamp"] = DateTime.Now;
return true;
}
return false;
}
The above method should work even if the behavior of the event is inconsistent (i.e. gets triggered once / twice / trice / n-times)
Example on how to use it:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
if (!Ok2Delete(e.RowIndex)) return;
// your logic goes here and the above IF statement
// will hopefully guarantee your code to run once.
}
Hope this will help others that might be facing the same issue.
I gave up on all the solutions I came up with once I realized that onload() event also gets fired twice.
And the worst part is when onload gets fired twice, the Page.IsPostBack sometimes returns false when it should return true, which automatically mess up all your initialization code.
Anyway, I finally understood the problem properly, it turns out there is a bug in the gridview that only happens if you use a command field of type image in one of your gridview columns.
You can avoid this error if you use a button type command field (instead of image).
Or in case you have to have an image to represent the delete button, you should completely ignore using the command field
and use a template field instead.
Here is how a delete button tag should look like in your .aspx file when using a template field:
Note: the example above shows how you can pass a value of another column on the same row that you wish to delete (ex: item_id
is a field of another column in the same row) to your event handler that can help you delete a record from the database.
You can also return the row number of the gridview in which you wish to delete by using
DataBinder.Eval(Container,"RowIndex")
instead of Eval(“your_column_name”)
And here is the code behind for handling the event “OnDelete”:
I "translated" Brad_M's to VB.NET in case anyone needs it: Private Function Ok2Delete(ByVal pRow As String) As Boolean If Session("RowIndex") Is Nothing OrElse _ (CInt(Session("Rowindex")) = pRow AndAlso DateTime.Now.Subtract(CDate(Session("RowIndexTimeStamp"))).Seconds
< 2) Then Session("RowIndex") = pRow Session("RowIndexTimeStamp") = DateTime.Now Return True End If Return False End Function And the function call: Protected Sub grd_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs)
Handles grd.RowCommand If Not Ok2Delete(e.CommandArgument.ToString()) Then Return End Sub I'm working with a String instead of an integer here because I'm handling the RowCommand event and not RowDeleting.
I "translated" Brad_M's to VB.NET in case anyone needs it:
Private Function Ok2Delete(ByVal pRow As String) As Boolean
If Session("RowIndex") Is Nothing OrElse _
(CInt(Session("Rowindex")) = pRow AndAlso DateTime.Now.Subtract(CDate(Session("RowIndexTimeStamp"))).Seconds < 2) Then
Session("RowIndex") = pRow
Session("RowIndexTimeStamp") = DateTime.Now
Return True
End If
Return False
End Function
And the function call:
Protected Sub grd_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles grd.RowCommand
If Not Ok2Delete(e.CommandArgument.ToString()) Then Return
End Sub
I'm working with a String instead of an integer here because I'm handling the RowCommand event and not RowDeleting.
Apparently the forum isn't very compatible with Opera. But this should work now...
Thanks for reporting the issue. This is a known issue and we are
investigating fixing this in the next service pack. For the time being
you could use the following work around. One obvious workaround is to
change the button type to a regular button or a link button. If you need
an ImageButton, then you can put an ImageButton in a TemplateField. You
may need to handle the Command event on the ImageButton and call
DeleteRow, passing the RowIndex as the CommandArgument, like this:
Brad_M
Member
240 Points
60 Posts
GridView RowDeleting event fires twice !
Jun 25, 2006 11:25 PM|LINK
I'm facing some annoying GridView behavior where it fires the RowDeleting event twice.
I'm doing the very normal (logical) steps for deleting a row from a GridView. Here is what I'm doing:
1- my test Page_Load method
protected void Page_Load(object sender, EventArgs e) { GridView1.DataSource = GetDataTable(); GridView.DataBind(); }2- the GridView has a Delete Command Field.
3- on tracing I've noticed my RowDeleting event gets fired twice! (also I used a static counter to see how many times the event gets fired when clicking on the GridView delete button, which was also confirmed it that it's counting 2 per each click).
Am I doing something wrong? please help
Brad_M
Member
240 Points
60 Posts
Re: GridView RowDeleting event fires twice !
Jun 26, 2006 10:22 AM|LINK
private bool Ok2Delete(int bypassCount) { Session["delCount"] = Session["delCount"] == null ? 0 : Session["delCount"]; return !((int)(Session["delCount"] = (((int)Session["delCount"]) + 1) % bypassCount) == 0); }just call it at the beginning of your RowDeleting event handling method. Example:
if (!Ok2Delete(2)) return; // parameter of 2 if event is firing twice // 3 if trice, etc...However, now that the event triggering twice is solve. But the funny part is (for me) the event turned out to be inconsistance in its behaviour (i.e. fires randomly either twice or one time).
And if someone else also facing similiar inconsistance behaviour, I'd advice to do like what I'll hopefully do; which is letting the user select the rows and clicks on a button (outside the grid) to delete them instead of embeded delete button within each row.
Brad_M
Member
240 Points
60 Posts
Re: GridView RowDeleting event fires twice !
Jun 26, 2006 06:50 PM|LINK
finally I found a proper solution for it. The problem seems a known ASP.NET issue.
Anyway, I wrote this method that needs to be called at the begninning of the event handling method:
private bool Ok2Delete(int ri) // ri is the record index to be deleted { if (Session["ri"] == null || (!((ri == ((int)Session["ri"])) && (DateTime.Now.Subtract((DateTime)Session["ri_time_stamp"]).Seconds < 2)))) { Session["ri"] = ri; Session["ri_time_stamp"] = DateTime.Now; return true; } return false; }The above method should work even if the behavior of the event is inconsistent (i.e. gets triggered once / twice / trice / n-times)
Example on how to use it:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e) { if (!Ok2Delete(e.RowIndex)) return; // your logic goes here and the above IF statement // will hopefully guarantee your code to run once. }Hope this will help others that might be facing the same issue.
LouG
Member
5 Points
1 Post
Re: GridView RowDeleting event fires twice !
Jul 06, 2006 08:06 PM|LINK
I just had the same problem. My solution turned out to be very easy...
Remove
AutoEventWireup="true"
in the Page directives from both the aspx form AND the Master page. I had to remove directive from both to effect the solution.
dvl_vn
Member
25 Points
5 Posts
Re: GridView RowDeleting event fires twice !
Aug 02, 2006 07:51 AM|LINK
I'm having this problem too. I will try your solutions. Thanks very much !
Brad_M
Member
240 Points
60 Posts
Re: GridView RowDeleting event fires twice !
Aug 03, 2006 08:54 PM|LINK
I gave up on all the solutions I came up with once I realized that onload() event also gets fired twice.
And the worst part is when onload gets fired twice, the Page.IsPostBack sometimes returns false when it should return true, which automatically mess up all your initialization code.
Anyway, I finally understood the problem properly, it turns out there is a bug in the gridview that only happens if you use a command field of type image in one of your gridview columns.
You can avoid this error if you use a button type command field (instead of image).
Or in case you have to have an image to represent the delete button, you should completely ignore using the command field and use a template field instead.
Here is how a delete button tag should look like in your .aspx file when using a template field:
<asp:TemplateField>
<ItemStyle HorizontalAlign="Right" Width="10%"/>
<ItemTemplate>
<asp:ImageButton runat="server" id="btnDelete" CommandName="cDelete" ImageUrl="../resources/images/delete1.gif"
CommandArgument='<%# Eval("item_id") %>' OnCommand="OnDelete" />
</ItemTemplate>
</asp:TemplateField>
Note: the example above shows how you can pass a value of another column on the same row that you wish to delete (ex: item_id is a field of another column in the same row) to your event handler that can help you delete a record from the database.
You can also return the row number of the gridview in which you wish to delete by using DataBinder.Eval(Container,"RowIndex") instead of Eval(“your_column_name”)
And here is the code behind for handling the event “OnDelete”:
protected void OnDelete(object sender, CommandEventArgs e)
{
if (e.CommandName.Equals("cDelete"))
{
try
{
string item_id = e.CommandArgument.ToString();
// your code to delete the item record from
// your database using the index item_id
}
catch (Exception) { }
}
}
laoujin
Member
14 Points
4 Posts
Re: GridView RowDeleting event fires twice !
Mar 19, 2007 09:24 AM|LINK
laoujin
Member
14 Points
4 Posts
Re: GridView RowDeleting event fires twice !
Mar 19, 2007 09:29 AM|LINK
I "translated" Brad_M's to VB.NET in case anyone needs it:
Private Function Ok2Delete(ByVal pRow As String) As Boolean If Session("RowIndex") Is Nothing OrElse _ (CInt(Session("Rowindex")) = pRow AndAlso DateTime.Now.Subtract(CDate(Session("RowIndexTimeStamp"))).Seconds < 2) Then Session("RowIndex") = pRow Session("RowIndexTimeStamp") = DateTime.Now Return True End If Return False End FunctionAnd the function call:I'm working with a String instead of an integer here because I'm handling the RowCommand event and not RowDeleting.
Apparently the forum isn't very compatible with Opera. But this should work now...
itsdanny
Member
21 Points
19 Posts
Re: GridView RowDeleting event fires twice !
Apr 12, 2007 12:12 PM|LINK
For what it's worth my solution/dirty hack
' Declare a global boolean
Public exitSub As Boolean = False
Sub DothisOnce(blah, blah)
If exitSub = True Then
Exit Sub
End If
' Do some coding/DB work or something
' code has ran so set boolean to true
ExitSub = True
End Sub
NB the sub still 'fires' twice still but exits as soon as the if statement is entered on the 2nd iteration. What a strange bug.
HTH[:|]
itsdanny
dstorfer
Member
54 Points
15 Posts
Re: GridView RowDeleting event fires twice !
Apr 23, 2007 05:21 AM|LINK
Here's a link to some information regarding Microsoft's awareness of this bug and a fairly good workaround that doesn't involve hacky flags:
http://www.issociate.de/board/post/285047/help_please_on_GridView_commands_+_AutoEventWireUp
Thanks for reporting the issue. This is a known issue and we are
investigating fixing this in the next service pack. For the time being
you could use the following work around. One obvious workaround is to
change the button type to a regular button or a link button. If you need
an ImageButton, then you can put an ImageButton in a TemplateField. You
may need to handle the Command event on the ImageButton and call
DeleteRow, passing the RowIndex as the CommandArgument, like this:
<asp:GridView ID="GridView1" runat="server"> <Columns> <asp:TemplateField> <ItemTemplate> <asp:ImageButton runat=server id="ImageButton1" CommandName="Delete" ImageUrl="..." CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>' OnCommand="ImageButton1_Command" /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> protected void ImageButton1_Command(object sender, CommandEventArgs e) { GridView1.DeleteRow(Int32.Parse(e.CommandArgument.ToString() )); }