0

I am using OnRowDataBound to automatically add a link button to my grid view that looks like this. The problem I am having is setting the command argument.

<asp:LinkButton ID = "lnkDelete" Text = "Delete" CommandArgument = '<%# Eval("Value") %>' runat = "server" OnClick = "DeleteFile" />

Below is the code that adds the links. I set the command argument to Eval("Value") but that doesn't work. Here is a link to the original code that I'm trying to change so it is dynamic.

protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        LinkButton lnkView = new LinkButton();
        lnkView.ID = "lnkDelete";
        lnkView.Text = "Delete";
        lnkView.Click += DeleteFile;
        lnkView.CommandArgument = Eval("Value");
        e.Row.Cells[1].Controls.Add(lnkView);
    }
Laserchalk
  • 5
  • 1
  • 3

1 Answers1

1

RowDataBound is not the right event to add controls dynamically because they need to be re-created on every consecutive postback. RowDataBound is triggered only if you call GridView.DataBind().

So use RowCreated instead, but assign the CommandArgument value in RowDataBound and don't use Eval("Value") but the actual datasource which you get from e.Row.DataItem.

Something like this should work:

protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        LinkButton lnkView = new LinkButton();
        lnkView.ID = "lnkDelete";
        lnkView.Text = "Delete";
        lnkView.Click += DeleteFile;
        e.Row.Cells[1].Controls.Add(lnkView);
    }
}

protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        LinkButton lnkView = (LinkButton)e.Row.FindControl("lnkDelete");
        var rowView = (DataRowView)e.Row.DataItem;
        lnkView.CommandArgument = rowView.Row.Field<string>("Value");
    }
}

If this throws an exception at runtime you need to change (DataRowView)e.Row.DataItem to the actual datasource which you can get from the debugger.

Edit: as commented it is a ListItem and you want to use it's Value property:

var item = (ListItem) e.Row.DataItem;
lnkView.CommandArgument = item.Value;
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I am using DataBind. The links are being created it's just that they aren't working. I'm only a beginner and I still don't understand what I need to be doing from your example. – Laserchalk Jan 27 '15 at 11:58
  • I think I understand it a bit better now. So with this part (DataRowView)e.Row.DataItem; Does "DataRowView" need to be my datasource? – Laserchalk Jan 27 '15 at 12:27
  • @Laserchalk: yes, it is the the single record in your datasource. It is a `DataRowView` if you use a `DataTable` as `DataSource`. If you use a different source you need to change the type. But what didn't you understand? Have you registered the event handler `OnRowCreated` and created the link there? What happened? – Tim Schmelter Jan 27 '15 at 12:31
  • @Time Schmelter I don't think I need OnRowCreated because I am using DataBind. It turns out I needed to change DataRowView to the type ListItem. The line under that isn't working, it says 'System.Web.UI.WebControls.ListItem' does not contain a definition for 'Row'. I'm guessing I need to use something different if I'm using a list item? – Laserchalk Jan 27 '15 at 13:16
  • @Laserchalk: Normally you don't need to DataBind the grid on every postback. You only need it if you refresh the source (f.e. if you use `Paging` or `Sorting`). If it's a `ListItem` cast it accordíngly and use it's `Value` property. I've edited m answer. – Tim Schmelter Jan 27 '15 at 13:25
  • thanks for the help it worked when I used OnRowCreated – Laserchalk Jan 28 '15 at 04:35