I am new to C# and am converting code from VB. My goal here is to fetch data from the gridview control using datakeys. The lines throwing errors are bolded and in italics. I am not sure if my code structure could be wrong or if the asp control is incorrect. Any help would be appreciated. Thanks
protected void gvDestroy_RowCommand(object sender, GridViewCommandEventArgs e)
{
string sReturn;
string sLoggedBy;
if (e.CommandName == "Delete")
{
odsDestroy.DeleteParameters.Add("mod_by", Session["username"].ToString());
}
if (e.CommandName == "Destroy")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gvDestroy.Rows[index];
sLoggedBy = cDestroyDP.fGetDestroy(***gvDestroy.DataKeys[index]***
("destroy_id").ToString).Rows[0]["logged_by"].ToString();
if (sLoggedBy == Session["username"].ToString())
{
lblError.ForeColor = System.Drawing.Color.DarkRed;
lblError.Text = "Operator cannot log and destroy same controls!";
}
else
{
sReturn = cDestroyDP.fDestroyControl(***gvDestroy.DataKeys[index]***
("destroy_id").ToString.Session["username"].ToString).ToString();
if (sReturn != "0")
{
lblError.ForeColor = System.Drawing.Color.DarkRed;
lblError.Text = sReturn;
}
else
{
gvDestroyed.DataBind();
gvDestroy.DataBind();
}
}
}
here is the gridview control
<asp:GridView ID="gvDestroy" runat="server" AllowPaging="True"
AutoGenerateColumns="False" DataSourceID="odsDestroy"
DataKeyNames="destroy_id" EmptyDataText="There Are No Controls To Be Destroyed At This
Time">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lbDelete" runat="server" CommandName="Delete"
OnClientClick="return confirm('Are you sure you want to delete this
record?');">Delete
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="entry_date" HeaderText="Date Entered" />
<asp:BoundField DataField="beg_control" HeaderText="Beg. Control" />
<asp:BoundField DataField="end_control" HeaderText="End Control" />
<asp:BoundField DataField="tot_control" HeaderText="Tot. Control" />
<asp:BoundField DataField="logged_by" HeaderText="Logged By" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnDestroy" runat="server" Text="Destroy"
CommandName="Destroy" CommandArgument="<%# CType(Container,
GridViewRow).RowIndex %>"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CodePudding user response:
DataKeys can have more then one value, but in most cases will only have one value.
In your case you have:
DataKeyNames="destroy_id"
So, in vb.net to get that, you need the row index AND ALSO the name.
eg this:
DataKeys("the row index goes here").Item("the data key name goes here")
So, you have this:
gvDestroy.DataKeys[index]("destroy_id").ToString
both parts are a array reference, and thus you need this:
gvDestroy.DataKeys[index]["destroy_id"]
And you probably don't even need the tostring.
So both the row index, and the name of the key are an array ref, and hence both need "[]" (square brackets).
The index reference is NOT a method of the datakeys array and thus BOTH are simple "index" reference into that collection, and thus BOTH need [] brackets to reference into that collection.
The first one is a row index, and the 2nd is a string key name. As noted, in MOST cases there is only one data key name, but OFTEN you can toss in a 2nd key name, even if it is NOT a key name.
The beauty of DataKey names, is you can have/use a PK row id in a gridview (or listview), and those PK id values are NEVER exposed client side, and thus you don't have to resort to say a hidden field, and other messy ways to have full use the row PK id from the database, but you NEVER expose such values to the client side browser (this is really nice for security reasons, since then you can continue to hide and not have to expose the PK values used in an application).
Edit, ok, having stated the above, you have this:
sLoggedBy = cDestroyDP.fGetDestroy(gvDestroy.DataKeys[index]
("destroy_id").ToString).Rows[0]["logged_by"].ToString();
That does not make sense.
This will get you the daykey value
cDestroyDP.fGetDestroy(gvDestroy.DataKeys[index]["destroy_id"]
But, what follows does not make ANY sense at all
eg:
Rows[0]["logged_by"].ToString()
Daykeys just returns a value of the data key field.
So, you THEN follow with a Rows[0] here?????
I mean, you seem to want the logged by value, and you seem to want the data key name value. Do you want to concentrate them together here - what do you want to happen?
You can get data key name with this:
MyDataKeyValue = cDestroyDP.fGetDestroy(gvDestroy.DataKeys[index]["destroy_id"]
And you get Logged_By with this:
MyLoggedByValue = row.cells[4].ToString()
So, there is no way to reference the data bound field by name (unless you build a helper function).
So keep in mind:
For templated controls in the GV, use .FindControl("control Name").
And for default columns (auto generated), or data bound columns, then you have to use the .Cells[] collection.
So, that's how you get the two values - now you just have to figure out what you want to do with the two values since your messy expression makes no sense at all.
And to get the logged_by value from the Grid row? Well, that is NOT a templated column, so you have to use .Cells[] collection - you can't use name.
you can use this:
string tt = gRow.Cells[4].ToString();