How to get the row index in the client side code of a DataItemTemplate in an ASPxGridView column

This was pissing me off for far too long today. I also have a DataItemTemplate with an ASPxHyperlink control in one of my columns of an ASPxGridView. When the user clicks the hyperlink, I need to call a JavaScript function that uses the index of that row in the grid… (Then, and this is outside the scope of this post but for information and context, I do a callback to the server side, look up some more specific information in the database, pass some data back to the client, and when the callback is complete, show a confirmation popup with a that shit data that I returned from the server. The user can then click an OK button on the popup which does another callback and that does some other stuff.) For some unknown reason, the complicated-sounding part was easy, but I got stuck on step one… How to get the index of the row in the grid where the link was clicked?

Consider that when the link is clicked, it nether sets the grid row selected nor focused. So the usual suspects (the devexpress controls’ functions to get visible row index or focused row index) are not helpful here… They return null.

So the column in the markup of the grid looks like this… (Nothing special here.)

<dx:GridViewDataTextColumn FieldName="Status" ShowInCustomizationForm="True" VisibleIndex="7">
        <dx:ASPxHyperLink ID="hlAuthorise" runat="server" Text='<%# Eval("Status") %>' OnInit="hlAuthorise_Init">

The JavaScript function that needs to be called when the link gets clicked is this… (Actually it’s not this, but you don’t need to see it. All that matters is it needs to be passed the index.)

        function AuthoriseClick(s, e, index) {

And the way to do it turns out to be easy. Just not so easy to find online. The trick is to set the index on the server side for each row, via the Init event of the hyperlink. (So I lied when I said there was nothing special above. If you scrolled to the right, you’d have noticed the Init event handler in the markup.) The C# code on the server-side is this:

        protected void hlAuthorise_Init(object sender, EventArgs e)
            /* This is the only way I've found to allow the client side code in a 
             * DataItemTemplate to get the index of the row in its container grid. */
            ASPxHyperLink link = sender as ASPxHyperLink;
            GridViewDataItemTemplateContainer container = ((ASPxHyperLink)sender).NamingContainer as GridViewDataItemTemplateContainer;
            link.ClientSideEvents.Click = String.Format("function (s, e) {{ AuthoriseClick(s, e, {0}); }}", container.VisibleIndex);

About Jerome

I am a senior C# developer in Johannesburg, South Africa. I am also a recovering addict, who spent nearly eight years using methamphetamine. I write on my recovery blog about my lessons learned and sometimes give advice to others who have made similar mistakes, often from my viewpoint as an atheist, and I also write some C# programming articles on my programming blog.
This entry was posted in Programming and tagged , , , . Bookmark the permalink.

2 Responses to How to get the row index in the client side code of a DataItemTemplate in an ASPxGridView column

  1. Eliza says:

    Thank you very very much for sharing this information! I was struggling with this for days!

    Liked by 1 person

    • Jerome says:

      Glad it helped…

      I have found another easier solution, though it might not be relevant to you. (It wasn’t relevant to me in the case where I needed to use a templated control.)
      You can also simply use a GridViewCommandColumnCustomButton, which, depending on the devexpress theme you’re using, may well render as a hyperlink anyway.

      For example, I have an ASPxGridView with one column that looks like this:

      <dx:GridViewCommandColumn VisibleIndex="13" ButtonType="Button" Caption=" ">
              <dx:GridViewCommandColumnCustomButton Visibility="AllDataRows" Text="Capture Sale">

      This has a couple of advantages:

      1. You can show/hide the button per row in the code-behind.
      2. You can handle the custom button click on the grid level, either in the code-behind or the client side.

      For example of decideding when to show/hide the buttons, you handle the grid’s CustomButtonInitialize event and in the code-behind, you can show/hide the button based on the value of columns in the grid, like this:

              protected void gvAllocated_CustomButtonInitialize(object sender, ASPxGridViewCustomButtonEventArgs e)
                  int allocated = Convert.ToInt32(gvAllocated.GetRowValues(e.VisibleIndex, "Balance"));
                  if (allocated == 0)
                      e.Visible = DevExpress.Utils.DefaultBoolean.False;

      In the above, if you have more than one custom button, the name of the button can be evaluated in the string e.ButtonID. (Yes, the ButtonID is a string and actually contains the name of the button.)

      Then if you handle the custom button click on the server-side (via CustomButtonCallback – not shown here), you can get the primary key of your grid using GetRowValues as above.

      And if you handle the click on the client side, you can do something like this… And notice we didn’t have to jump through hoops to access the row index.

      <ClientSideEvents CustomButtonClick="function(s, e) { CaptureSaleClick(s, e, e.visibleIndex); }" />

      Hope this makes sense, as I don’t have time to write this in a proper post.


    Leave a Reply

    Fill in your details below or click an icon to log in: Logo

    You are commenting using your account. Log Out /  Change )

    Google photo

    You are commenting using your Google account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s