按钮上的GridView行重定向到预填充的DetailsView单击

时间:2011-10-18 23:49:27

标签: asp.net vb.net gridview detailsview

背景

我有一个GridView,它通过DataSourceID从SqlDataSource填充。这些行显示了SQL视图中的一些摘要数据。单击一行后,我想将我的用户带到另一个带有DetailsView控件的页面,该控件将填充与所单击的行相关的完整值集。我的用户应该能够编辑数据,下载与记录关联的文件,并根据所述数据创建不同类型的新记录。

错误

我为Clickable GridView行找到的所有示例最终都会出现错误Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.

的某些变体

当然,我不希望通过禁用事件验证来将我的网站暴露给漏洞。我需要能够获取所单击行的相关记录的主键,并在后续页面上对该数据执行操作,可能是通过DetailsView。我怀疑我的错误是我的设置的结果,这就是我将这些细节包括在内的原因。

我的问题

  1. 如何捕获点击行的主键?
  2. 我如何点击转发到“详情”页面,其中包含预先填写的表格,其中包含点击的行记录中的数据?
  3. 这里是完整的解决方案

    **再次感谢伊卡洛斯的帮助

    'Fetch the DataKey ("ID"), seems to work
    Protected Sub RowBind(ByVal sender As Object, ByVal e As GridViewRowEventArgs) _
        Handles GridView1.RowDataBound
    
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString()
        End If
    End Sub
    'Handle button click
    Protected Sub RowClick(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) _
        Handles GridView1.RowCommand
    
        If e.CommandName = "Select" Then
            'Add to session variable; translate the index of clicked to Primary Key
            Session.Add("DetailsKey", GridView1.DataKeys(e.CommandArgument).Value.ToString)
            Response.Redirect("details.aspx")
        End If
    End Sub
    

    和我的标记

    <asp:GridView ID="GridView1" runat="server" DataSourceID="GridView1SDS"
        DataKeyNames="ID" AllowPaging="True" AllowSorting="True">
        '<!-- Styling -->
        <Columns>
            <asp:ButtonField ButtonType="Button" Text="Details" CommandName="Select" />
        </Columns>
    </asp:GridView>
    <asp:SqlDataSource ID="GridView1SDS" runat="server"
        ConnectionString="<%$ ConnectionStrings:dbConnectionString %>"
        SelectCommand="select * from viewRequestQueue">'<!-- An SQL View -->
    </asp:SqlDataSource>
    

    转发页面VB&amp;标记

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            GridView2SDS.SelectCommand = "select * from viewRequestQueue where ID = " _
                + Session.Item("DetailsKey").ToString
        End If
    End Sub
    
    <asp:DetailsView ID="GridView2" runat="server" DataSourceID="GridView2SDS">
        '<!-- Styling -->
    </asp:DetailsView>
    <asp:SqlDataSource ID="GridView2SDS" runat="server"
        ConnectionString="<%$ ConnectionStrings:dbConnectionString %>">
    </asp:SqlDataSource>
    

    另外,请注意,如果在代码隐藏中处理数据源的SelectCommand,则表示DataBind将覆盖标记中的<Columns>。要解决这个问题,您应该在DataBind之前的代码中定义列。所以说我想在转发的页面中添加另一个ButtonField列(注意标记中没有提供SelectCommand),我在设置SelectCommand和执行DataBind之前添加了以下内容:

    Dim id As New ButtonField()
    id.ButtonType = ButtonType.Button
    id.Text = "Load"
    id.CommandName = "Select"
    PubDetails.Columns.Add(id)
    

1 个答案:

答案 0 :(得分:2)

您需要声明您在标记上绑定的项目的KeyNames。例如:

<asp:GridView id="grid" runat="Server" DataSourceID="YourSQLDataSource" DataKeyNames="ID,Name" />

在您的情况下,您似乎正在处理OnRowDataBound事件。您可以这样做以获取RowBound中的键:

If e.Row.RowType = DataControlRowType.DataRow Then
  Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString()  'get the datakey
End If

您的第二个问题很难回答,因为您没有指定如何从客户端使用Javascript或从服务器端重定向用户。您还没有指定如何填充“详细信息”页面上的详细信息。您是否希望从URL读取参数并使用它从数据库中获取记录详细信息?