Why doesn't my GridView SelectedIndexChanged event fire?
Solution 1
Don't you need a column CommandField
defined as a SelectButton
? Then, your markup would look something like:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:HiddenField runat="server" ID="hdnScrollPosition" />
<asp:GridView ID="gridMessages" runat="server" CssClass="gridView" AutoGenerateColumns="False"
AllowPaging="true" GridLines="None" PageSize="10" ShowHeader="True"
EmptyDataText="--No Messages Received--" Width="100%">
<Columns>
<asp:CommandField ShowSelectButton="true" ButtonType="Button" />
<asp:TemplateField HeaderText="Messages Received" HeaderStyle-HorizontalAlign="Left" HeaderStyle-CssClass="headerClass">
<ItemTemplate>
....
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
You didn't ask about this, but I always feel compelled to mention things like these two lines:
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#D2E6F8'")
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='#ffffff'")
This is a code smell. It's not a bad one, but mixing JavaScript attributes with VB/C# code is a habit you should break out of now. If you need to do something like this, add a CssClass
property to your GridView and define those actions in CSS (or JavaScript/jQuery if CSS doesn't have enough events for you).
Edit:
Based on our discussion in comments, this looks like an inconsistency with the way the GridView can be modified. It may be related to the page/event lifecycle (somehow it's too late for ASP.NET to properly hook up the events?), and your best bet here is to switch from the SelectedIndexChanged
event to SelectedIndexChanging
.
Solution 2
I've been wrestling with the same issue...
It may not work in your scenario (or be a good thing to do at all) but try setting EnableEventValidation="false"
for the page. This was the difference for me. Worked using either SelectedIndexChanged
or SelectedIndexChanging
events as mentioned above.
Comments
-
jdtaylor almost 2 years
I have a
GridView
which you can click on a row and it should call theSelectedIndexChanged
method (which updates another part of the page based on which row was selected). I have done something similar to this before and it worked, but I can't seem to get theSelectedIndexChanged
part to be called for some reason.The page is held in a master page which has a
form runat="server"
tag, and an<asp:ScriptManager>
tagI am using
e.Row.Attributes.Add("onclick", ClientScript.GetPostBackClientHyperlink(Me.gridMessages, "Select$" & e.Row.RowIndex))
to allow theSelectedIndexChanged
to fire by clicking anywhere on the row.To check that the code does work apart from that, I added a
CommandField
with aSelectButton
and that successfully fires, but i would prefer to find a solution without having to use that.code is below - any help would be appreciated. Thanks
GridView
:<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always"> <ContentTemplate> <asp:HiddenField runat="server" ID="hdnScrollPosition" /> <asp:GridView ID="gridMessages" runat="server" CssClass="gridView" AutoGenerateColumns="False" AllowPaging="true" GridLines="None" PageSize="10" ShowHeader="True" EmptyDataText="--No Messages Received--" Width="100%"> <Columns> <asp:TemplateField HeaderText="Messages Received" HeaderStyle-HorizontalAlign="Left" HeaderStyle-CssClass="headerClass"> <ItemTemplate> .... </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </ContentTemplate> </asp:UpdatePanel>
Code-Behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Me.gridMessages.DataSource = ... Me.gridMessages.DataBind() End If End Sub Protected Sub gridMessages_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gridMessages.RowDataBound If e.Row.RowType = DataControlRowType.DataRow Then e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#D2E6F8'") e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='#ffffff'") e.Row.Attributes.Add("onclick", "saveScrollPosition(); " & ClientScript.GetPostBackClientHyperlink(Me.gridMessages, "Select$" & e.Row.RowIndex)) End If End Sub
SelectedIndexChanged
(which never fires):Protected Sub gridMessages_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles gridMessages.SelectedIndexChanged Response.Redirect("test.aspx") End Sub
-
jdtaylor over 12 yearsI'm trying to avoid having to actually use a button to select a row, which was why i added the extra attribute below the two above (thanks for the advice on splitting up the code - will do that). The e.Row.Attributes.Add("onclick", ClientScript.GetPostBackClientHyperlink(Me.gridMessages, "Select$" & e.Row.RowIndex)) line should work so that the gridview doesn't need the commandfield. thoughts?
-
jwheron over 12 yearsHmm...I've never tried something like that. I'm not sure what ASP.NET will listen for if you don't have the button created (you may very well be right, and it might work just fine without the button). Maybe try creating the button to make sure you have the postback hyperlink stuff exactly right? That would be a good detail to edit back into the original question, I think.
-
jdtaylor over 12 yearsjust added the button and the SelectedIndexChanged fires when using that. I've used the onclick attribute before and it worked, so am unsure why it doesn't with this
-
jdtaylor over 12 yearsbtw thanks for the tweaks to the question, makes more sense now!
-
jwheron over 12 yearsNo problem. I minored in English in college, so I have to make use of that education somehow. :) Does JavaScript generated by the button you added match what you were building in code-behind for the row itself?
-
jdtaylor over 12 yearsYeah it matches, I tried removing it to see if that was the problem and it didn't make any difference.
-
jwheron over 12 yearsDoes it work if you remove the call to
saveScrollPosition();
? I just tried this myself on one of my projects, and it worked properly in Firefox 8.0. Maybe it's a browser issue as well? -
jdtaylor over 12 yearsI've removed that and it now works, but only if I keep the
CommandField
in. The strange thing though is it only fires when there is aResponse.Redirect("test.aspx")
in theSelectedIndexChanged
If i put aResponse.Write("...")
or just change a label valueMe.lblName.Text = "this"
it doesn't fire and none of these change. Bit confusing why its only firing if there's aResponse.Redirect()
! -
jdtaylor over 12 yearsafter looking through it, it turns out that the
SelectedIndexChanged
method doesn't like me usingMe.gridMessages.SelectedRow
whenever I do that it refuses to fire, but if its removed everything else works. Is there an alternative way to get the selected row index? -
jwheron over 12 yearsCan you use the
SelectedIndexChanging
event instead? There, you'll have access toe.NewSelectedIndex
, which you can use to accessgridMessages.Rows[e.NewSelectedIndex]
. -
jdtaylor over 12 yearsThanks - works perfectly with
SelectedIndexChanging
looks like all the errors are fixed now, thanks - you've helped me out alot! -
jwheron over 12 yearsNo problem at all -- I learned a few things in this experience myself. I'll update the answer according to our discussion here.