I like GridView, but using it is a sometimes like getting behind the wheel of a 747 without ever flying before.
I have a software tracking report to make that pulls data out of database using an SQLDataSource. Everything in the database is keyed on the computer name, so to make a list of installed applications across the domain, I do a GROUP BY on application name and version in the select statement. The report displays the name, version, and count in a GridView. To get the list of computers where a particular application name and version instance is installed, I query the database on GridView select. But since it’s a GROUP BY, there is no permanent primary key, and so I need to know both the application name and the version for the query.
To get this information in the select handler I thought I’d use
gdvApplications.SelectedRow["name"]
gdvApplications.SelectedRow["version"]
but it turns out there are no indexers defined on the SelectedRow. Then I read about DataKeyNames. You can set this property of the GridView to the name(s) of one or more (comma separated) of your columns, and then something will show up in the SelectedValue property. In fact, this is supposed to be used to get PrimeryKey values out of a selected row.
gdvApplications.DataKeyNames = "name,version"; // In Page_Init() or correspondingly
//in the aspx/ascx file.
(...)
gdvApplications. SelectedValue["name"];
gdvApplications.SelectedValue["version"];
Except, er, well, no. There are no indexers defined on SelectedValue either. In fact it is just an object and corresponds only to the first column that is defined in DataKeyNames. To cut to the chase, if you have multiple DataKeyNames defined, here is how you can access them:
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values["name"];
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values["version"];
And yet it looks so simple in Visual Studio, you just drag and drop the GridView on your web form like a text box and follow the wizards. I’m glad that it can be done, but why wouldn’t we just have row indexers? Anyway, this is really more of a case of “I let the IDE lead me by the nose (and it led me into a brick wall.)” Not the first time for me…
Update 8/2009
Thank you very much for all of the wonderful comments!
If you liked this post, feel free to find me at Linked In, Gregory Graham, Greater Chicago Area, Banking.
It works! Thanks for the posting. I also tried your first 2 attempts without success. This is very helpful.
Thank you,
BN
I found this helpful.
Thanks
I found it very useful.
Thanks.
I am a noob. Can you spell out the context that
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values[”name”];
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values[”version”];
should be placed in?
Thanks!
Found a Helpful Article. Thank u.
This article has been in my list of most wanted for a while
Really helpful article.
Thanks!
This really helped me with using multiple DatakeyNames and hidden cells, thank you!
Hey, thanks buddy….
This article is very help full to me.
hi,
i tried to use the code
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values[”name”];
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values[”version”];
to get the values of the datakeys of the selected row.
it gives me object reference not set to an instance of an object error.
could you tell me why.
Thanks very much for taking the time to post this – it was very helpful!
I have seen your code on how to get multiple datakeyvalues fromthe row select. How can I pass multiple value back into another control (such as a detailsview). I am using SelectCommand=’SELECT * From “GPT_INTER_ADJUSTMENT_ERR” WHERE LOAD_SEQ_ID = :dkSeqNo’ >
where dkSeqNo is the first datakey value I obtained inside of GridView1_SelectedIndexChanged. Where would I code for additional datakeys inside ?
Why not use gdvApplications.SelectedDataKey.Values["whatever"]?
Saves a step for me.
Thank you so much~~~
Thanks,
This solution was very useful to us.
Particularly when there is case of multiple columns in Primary Key and you want to retrieve the value of a particulat column.
Once again thanks a lot.
Thank you. Very helpful.
And in the case where I’ve got multiple detailviews based off multiple keys in the selected gridview… where I was using a linqdatasource, but switching to an objectdatasource (gotta start thinking about business rules once you’ve got the prototype working).
I ran into this again and had to figure it out again. If you use the datasource “properties” to edit this (since I just can’t figure out how to write asp directly).
So, based on you name and version, datasources (object and linq) keying off the version from a gridview1, would look like-
Maybe I need to blog this myself to properly knock it in my head so I don’t keep solving the same problem over and over!!!!
Thanks, reading this blog stirred enough braincells so I knew what to do.
john.
”
“
Gud one graham.
Keep posting such commmon scenarios where developers get strucked.
Google on Datakeynames and you came a very well deserved 5th. long may you prosper. Thanks Ian, http://www.ava.co.uk
Good article but for work for ASP.NET with VB.NET do these very minor changes
gdvApplications.DataKeyNames = New String() {“name”,”version”}
It doesnt work for me..i have been trying to fix this problem for a long time
here is a part of my gridview
<asp:GridView ID=”gvEventsList” runat=”server”
AutoGenerateColumns=”False”
DataSourceID=”odsEventsList”
EmptyDataText=”No Events”
AllowSorting=”true”
DataKeyNames=”EventID,LastUpdatedOn”
And this is my code behind for the object data source deleting event
String eventID = gvEventsList.DataKeys[gvEventsList.SelectedIndex].Values["EventID"].ToString();
but it gives and error ” Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index ”
the problem is that gvEventsList.SelectedIndex is returning a value -1 . Why is it so ?is it somehow related to the link i used in the template field in the gid view ?? can somebosy plz help me out ??
helpful article.
Hello and thanks for the post… just a question as I’m a newbie…
How am I supposed to use DataKeyNames inside a “manual query”?
e.g. SELECT TCustomer as Client, TFirstName as Name FROM Table
What would be the DataKeyName for the first column, in this case?
TCustomer or Client?
Or none of them (in this case how should the DataKeyName be configured?)?
Thanks for letting me know,
–Paolo
Should be “Client” I suppose. I haven’t tried it though.
[...] You can also check a similar kind of article here [...]
This article was simple and easy to understand!!! Thanks a lot for the effort!!!
Thanks!,
Hai,
To resolve this issue, try this one
protected void gvPopulate_SelectedIndexChanged(object sender, EventArgs e)
{
TextBox1.Text = “”;
TextBox1.Text = gvPopulate.SelectedPersistedDataKey[0].ToString() + “,” + gvPopulate.SelectedPersistedDataKey[1].ToString();
}
It surely helps you…
for the other newbies who are struggling with the gridview..
gdvApplications.DataKeyNames = “name,version”;
should have been
gdvApplications.DataKeyNames = new string[]{“name,version”}
I kept seeing on the Microsoft site that you could define multiple fields in the DataKeyNames but nowhere did it explain how to access them. I was spinning my wheels trying to figure it out. You saved me! Thanks.
There is an issue with multiple-field DataKeys in GridView. Delete command of the GridView will pass to the underlying datasource all fields used in data keys as parameters. This throws an error, since most probably the datasource doesn’t have all data key fields as parameters (it ussually is using a single field primary key). Adding fictious parameters to the datasource just to workaround this issue is making dificult to manage the changes in your BLL/DAL.
Gregory,
You may want to look at this:
http://www.dotnetwatch.com/Multiple-datakeynames-in-gridview2693_MSG.aspx
Thanks, much appreciated!
I’d just like to point out alternatives to
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values["name"];
This also works -
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Item["name"];
As well as these less useful versions,
with an integer variable which represents the order of the datakeys -
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values[ipos];
gdvApplications.DataKeys[gdvApplications.SelectedIndex].Item[ipos];
Very, very helpful when required to work with multiple field primary keys! Thank you so much for posting this!
There is a shortcut version to the same thing, at least where a row is selected:
in VB:
gdvApplications.DataKeys(gdvApplications.SelectedIndex).Values(“name”)
..can be rendered more simply as:
gdvApplications.SelectedDatakey(“name”)
or as per Madhava’s post above:
gdvApplications.SelectedPersistedDatakey(“name”)
Unfortunately, if you are retrieving the key for an unselected row, there seems to be no alternative to the long route, eg in _RowDataBound sub:
GVblog.DataKeys(e.Row.DataItemIndex).Values(“ThreadID”)
I have to say a big thanks. Your post saved the day. I had to make a change as I was using the RowCommand override and needed to get the index value first. But it works great. Thanks so much. I case it helps someone else I have included my working version here.
protected void gvCustomersListEdit_RowCommand(object source, GridViewCommandEventArgs e)
{
switch (e.CommandName)
{
case “edit_entry”:
//gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values["name"];
ViewState["Edit"] = gv_Vendors.DataKeys[int.Parse(e.CommandArgument.ToString())].Values["VendorKey"];
MultiView1.SetActiveView(editView);
lbl_CustomerKey.Text = ViewState["Edit"].ToString();
break;
}
}
Hi,
the correct code to get multiple DataKeyNames is the following:
option 1
stringkey1 = gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values["name"].ToString();
stringkey2 = gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values["version"].ToString();
option 2
stringkey1 = gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values[0].ToString();
stringkey2 = gdvApplications.DataKeys[gdvApplications.SelectedIndex].Values[1].ToString();
This both options will retrieve the keys.
Thanks!!!
I spent 2 days, trying gets values from two fields. After I read your article my problem has disapeared in 5 minutes.
great post….kudos..
Big Thanks
[...] July 8, 2009 in dotnet One of the humbling (and slightly frustrating) parts of switching technology stacks is learning how to do something you knew by heart in the old tech. Case in point: figuring out which item you selected in a GridView in ASP.net. I had a pattern down cold for this in Java web development. I eventually found the DataKeys property of GridView, but the online help did not describe how to use multiple keys. Thanks to the internet, I found a very helpful answer (and it’s not intuitive) here. [...]
Thank you so much for this post. I spent a couple of days in frustration trying to get my UpdateCommand to work. I followed your suggested method of passing multiple parameters and it worked!
Check out the second example:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.selecteddatakey.aspx
First much thanks for writing this aritcle!!!!!
I found I was able to retrieve the value of the my second datakey by using SelectedValue instead of SelectedIndex.
Me.GridView1.DataKeys(GridView1.SelectedValue).Values(“PublicationId”)
Thanks again for this article