获取 GridView 行

3

我有一个GridView,我在Page_Load中将其绑定到SqlDataReader上。它有一列带有按钮,我试图使用以下代码获取单击按钮时的行:

int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[index];

编辑:将评论部分的.aspx页面粘贴如下:

 <asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333" OnRowCommand="GridView1_RowCommand" DataKeyNames="id" GridLines="None"> <AlternatingRowStyle BackColor="White" /> 
    <Columns> 
        <asp:TemplateField> 
             <ItemTemplate> 
                  <asp:Button ID="btnChange" runat="server" Text="Change" CommandName="Test" Visible='<%# Convert.ToBoolean(Eval("Tested")) == true ? true : false %>' /> 
             </ItemTemplate> 
         </asp:TemplateField> 
     </Columns>
</aspx:GridView> 

我遇到了以下错误:'System.FormatException: 输入字符串的格式不正确。',出错代码为'int index = Convert.ToInt32(e.CommandArgument);'。
有任何想法吗?

你是否在 int index=.. 上设置了断点并检查了 e.CommandArgument 是什么?它很可能是一个无法转换为整数的值。 - Ta01
1
你有没有仔细检查过 e.CommandArgument 的值?文档指出,当“值不包含一个可选符号和由数字 (0 到 9) 组成的序列”时,会抛出 FormatException 异常。http://msdn.microsoft.com/en-us/library/sf1aw27b.aspx - Bryan Crosby
你是在OnRowCommand事件中做这个吗? - Emaad Ali
我检查了commandArgument并且是“”。但为什么会发生这种情况?@Emaad Ali 是的,我正在GridView1_RowCommand上执行此操作。 - pikk
你能发布一下设置命令参数的.aspx页面吗? - Vinay
显示剩余2条评论
4个回答

6
你需要检查GridView行中哪个命令被点击了。你的标记应该相应地进行映射。看下面的例子。 你获取的e.CommandArgument可能与你的按钮点击不对应。
在CodeBehind中:
    void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
    {
    // If multiple buttons are used in a GridView control, use the CommandName property to determine which button was clicked.
    if(e.CommandName=="Add")
    {
    // Convert the row index stored in the CommandArgument property to an Integer.
    int index = Convert.ToInt32(e.CommandArgument);

    // Retrieve the row that contains the button clicked by the user from the Rows collection.
    GridViewRow row = CustomersGridView.Rows[index];

    // additional logic...
    }
    // additional logic...
}

在标记中:
另外,请确保您已经适当设置了CommandArgument属性。以下是示例:
<asp:Button (...) CommandArgument="<%# Container.DataItemIndex %>" />

或者使用一个按钮字段

<asp:ButtonField ButtonType="button" CommandName="Add" Text="Add" />

1
ButtonField会自动将CommandArgument填充为行的索引;而使用普通的Button OP则需要显式设置CommandArgument。只是澄清一下区别,你们的方法都是正确的。 - Tim
谢谢Tim,我正在根据你的评论编辑答案。 - Kash

1

你能贴出整个标记代码吗?这样更有助于解决问题。根据你的问题,在gridview的aspx代码中,你需要在按钮控件中使用Command Name和Command Argument,并且它应该绑定到数据库的一列中。使用gridview的Row Command事件。同时尝试使用Item Template把控件放在gridview内部。

点击这里查看MSDN文档. GridView中的Row Command事件

protected void Grid_RowCommand( object sender, GridViewCommandEventArgs e )
{
    int index = Convert.ToInt32( e.CommandArgument );
    your logic .......
}

0

您尚未为命令参数添加值。针对您在 .aspx 页面上的按钮事件

<asp:Button ID="btnChange" runat="server" Text="Change" CommandName="Test" CommandArgument = 1 Visible='<%# Convert.ToBoolean(Eval("Tested")) == true ? true : false %>' /> 

在代码后台,即RowCommand事件中。
if(e.CommandName == "Test")
{
int index = Convert.ToInt32(e.CommandArgument);
}

这仅适用于值1。为了使其通用,您可以使用绑定技术之一将命令参数绑定到所需的值,例如:CommandArgument ='<%# Eval("ID") %>'(假设GridView中存在ID)


第一种方法只适用于第二行(CommandArgument =“1”)。您的第二种方法(绑定在“ID”上)可能无法正常工作,因为您做出了(危险的)假设,即ID字段将与行索引匹配。 - Tim
第一个例子只是为了演示您需要在.aspx页面中指定命令参数。第二种方法是让他们知道他们也可以绑定事件。我确实理解它只能与gridview的列ID绑定。 - Vinay
OP(或者以后看到这个问题的人)可能没有意识到这只是一个示例,用来展示如何完成。我建议您编辑您的答案,使其更加清晰 - 只因为您(或我)知道您的意思,并不意味着经验较少或全新的开发人员也会明白。 - Tim
是的,我明白了。我刚刚编辑了答案。如果这样还有疑惑,请告诉我。 :) - Vinay

-1

看看这段代码

void ContactsGridView_RowCommand(Object sender,GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
if(e.CommandName=="Add")
{
  // Convert the row index stored in the CommandArgument
  // property to an Integer.
  int index = Convert.ToInt32(e.CommandArgument);

  // Retrieve the row that contains the button clicked 
  // by the user from the Rows collection.
  GridViewRow row = ContactsGridView.Rows[index];

  // Create a new ListItem object for the contact in the row.     
  ListItem item = new ListItem();
  item.Text = Server.HtmlDecode(row.Cells[2].Text) + " " +
    Server.HtmlDecode(row.Cells[3].Text);

  // If the contact is not already in the ListBox, add the ListItem 
  // object to the Items collection of the ListBox control. 
  if (!ContactsListBox.Items.Contains(item))
  {
    ContactsListBox.Items.Add(item);
  }
 }
}    

以下是用于网格视图的HTML代码
<asp:gridview id="ContactsGridView" 
          datasourceid="ContactsSource"
          allowpaging="true" 
          autogeneratecolumns="false"
          onrowcommand="ContactsGridView_RowCommand"
          runat="server">

          <columns>
            <asp:buttonfield buttontype="Link" 
              commandname="Add" 
              text="Add"/>
            <asp:boundfield datafield="ContactID" 
              headertext="Contact ID"/>
            <asp:boundfield datafield="FirstName" 
              headertext="First Name"/> 
            <asp:boundfield datafield="LastName" 
              headertext="Last Name"/>
          </columns>

        </asp:gridview>

检查链接 Gridview 命令

希望这个答案能帮到你。


但错误出在 int index = Convert.ToInt32(e.CommandArgument);。 - pikk
@nevayeshirazi,伙计,你真有趣。 - Emaad Ali
如果 (e.CommandName == "Test") int index = Convert.ToInt32(e.CommandArgument); GridViewRow row = ((GridView)e.CommandSource).Rows[index];。它有正确的命令,因为它进入了 If 语句。 - pikk
你可以查看我上面发布的Vinay的.aspx源代码。 - pikk
请检查我在答案中提到的链接。 - Emaad Ali
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接