将ASP.Net GridView从一个页面传递到另一个页面

7

我希望能将所有的GridView值传递到另一个页面。 在PatientDetails.aspx页面上有一个GridView和一个按钮,如下所示:

<asp:GridView ID="gvDoctorList" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" 
    AllowPaging="True" AllowSorting="True" AutoGenerateEditButton="true" AutoGenerateSelectButton="true"
    AutoGenerateDeleteButton="true" OnSelectedIndexChanged="gvDoctorList_SelectedIndexChanged" OnRowCommand="gvDoctorList_RowCommand">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:CheckBox runat="server" ID="chk" OnCheckedChanged="chk_CheckedChanged" AutoPostBack="true" />
                <asp:Label runat="server" ID="lblPID" Visible="false" Text='<%# Eval("PatientId") %>'></asp:Label>
                <asp:Button ID="btnSelect" runat="server" Text="Select" CommandName = "Select" />
            </ItemTemplate>
        </asp:TemplateField>

        <asp:BoundField DataField="PatientId" HeaderText="PatientId" SortExpression="PatientId" />
        <asp:BoundField DataField="firstname" HeaderText="firstname" SortExpression="firstname" />
        <asp:BoundField DataField="lastname" HeaderText="lastname" SortExpression="lastname" />                                
        <asp:BoundField DataField="sex" HeaderText="sex" SortExpression="sex" />
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyDatabaseConnectionString %>" 
    SelectCommand="SELECT [PatientId],[firstname], [lastname], [sex] FROM [PatientDetails]"></asp:SqlDataSource>
<asp:Button ID="btnformatric" runat="server" Text="formatric3d" OnClick="btnformatric_Click" OnCommand="btnformatric_Command" />

在PatientDetails.aspx的codebehind中,代码如下:
protected void btnformatric_Click(object sender, EventArgs e)
{
    if (gvDoctorList.SelectedRow != null)
    {
        Server.Transfer("Patientstaticformatrix.aspx");
    }
    else
    {
        ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Please select a row.')", true);
    }
}

现在在第二个页面,名称为Patientstaticformatrix.aspx,其后台代码如下:
protected void Page_Load(object sender, EventArgs e)
{
    if (this.Page.PreviousPage != null)
    {
        GridView gvDoctorList = (GridView)this.Page.PreviousPage.FindControl("gvDoctorList");

        GridViewRow selectedRow = gvDoctorList.SelectedRow;
        Response.Write("PatientId: " + selectedRow.Cells[0].Text + "<br />");
        Response.Write("firstname: " + selectedRow.Cells[1].Text + "<br />");
        Response.Write("lastname: " + selectedRow.Cells[2].Text + "<br />");
    }
}

我已经在第二页调试了代码... gvDoctorList的值为空,而selectedRow显示空引用错误。

请问我错在哪里?


为什么要转移控制权 - 更简单的选择是访问绑定到网格的数据。 - NoviceProgrammer
我想要将patientid的值传递到另一个页面,除此之外不需要其他内容...并且想要在第二个页面中插入所选患者的patientid和图像。 - Pratik
6个回答

4
尝试使用会话变量。您可以将GridView设置为会话变量,只要相同的会话仍然活动,就可以随后检索它。
您可以使用以下代码在第一个页面上设置Session Variable:
Session["gvDoctorList"] = gvDoctorList;

然后在第二个页面从变量中检索:

GridView gvDoctorList = (GridView)Session["gvDoctorList"];

更多有关Sessions的信息,请参阅MSDN会话状态概述


我应该在复选框更改事件中设置会话还是其他地方? - Pratik
您可以在任何地方设置会话变量,但我建议在需要时再进行设置。例如在 btnformatric_Click 中使用以下代码:Session["gvDoctorList"] = gvDoctorList; Server.Transfer("Patientstaticformatrix.aspx");。这样可以避免浪费内存空间。 - Nunners
我无法直接在会话中获取gridview控件gvDoctorList...这意味着我需要先设置gridview的循环,然后在其中设置会话值...你觉得呢? - Pratik
1
被踩了。不好的做法。在内存消耗和性能方面,对象太大无法保存在会话中。即使它能工作,你也永远不应该这样做。否则你将会遭受巨大的打击。 - Ahmed ilyas
@Ahmedilyas,请查看我下面的新扩展答案。我认为我已经解决了使用Session变量的任何问题,就像这个答案一样。 - Nunners

4

我看到您之前的问题,我可以建议您一件事情,不要使用昂贵的会话来保存您的网格视图,而是使用 RowCommand 事件,在这里有 button 后,我认为您不需要复选框或 chk_CheckedChanged 事件,您可以将 PatientID 传递到下一页,然后在那里编写查询以将所选行数据插入到新表中。

 <asp:TemplateField>
       <ItemTemplate>
        <asp:CheckBox runat="server" ID="chk" OnCheckedChanged="chk_CheckedChanged"  
         AutoPostBack="true" />
        <asp:Label runat="server" ID="lblPID" Visible="false" Text='<%# Eval("PatientId") %>'> 
       </asp:Label>
      <asp:Button ID="btnSelect" runat="server" Text="Select" CommandArgument='<%# 
       Eval("PatientId") %>' CommandName = "Select" />
      </ItemTemplate>
    </asp:TemplateField>



 protected void gvDoctorList_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "select")
            {
                int pID = Convert.ToInt32(e.CommandArgument);
                // either put ID in session and check 
                Session["PatientID"] = Convert.ToString(pID);
                Server.Transfer("Patientstaticformatrix.aspx");
            }
        }

在页面加载事件中
 protected void Page_Load(object sender, EventArgs e)
    {
         string pID = Convert.ToString(Session["PatientID"]);
            if(!string.IsNullOrEmpty(pID))
            {
              int patientID = Convert.ToInt32(pID);
             //Call Stored procedure which will insert this record with this ID
             // to another table
            }    

    }

我用你的代码尝试了一下,但是在这一行出现了错误:int pID = Convert.ToInt32(e.CommandArgument); 报错信息为“输入字符串格式不正确”……这该怎么办? - Pratik
patientid在SQL服务器中是整型数据类型,并且具有自动增量属性。 - Pratik
你是否在GridView中设置了CommandArgument,就像这样 <asp:Button ID="btnSelect" runat="server" Text="Select" CommandArgument='<%# Eval("PatientId") %>' CommandName = "Select" /> - Suraj Singh
patientid 是主键,不允许为空。 - Pratik
是的,现在它运行得很好......我放置了命令参数....非常感谢,它确实有帮助。 - Pratik
显示剩余3条评论

3

我决定根据Ahmed的正确评论添加第二个答案。由于内存问题,会话变量确实不应该保存gridview的数据量。

以下应该可以按照我所假设的方式正常工作:

基本上,当您选择要进入下一页的行时,您正在尝试检索该行的数据以在新页面上使用。这个假设是正确的吗?如果是,那么您有许多选项可供使用。

同样,您可以使用会话变量在第一页提取后存储该行的数据:

protected void btnformatric_Click(object sender, EventArgs e) {
    if (gvDoctorList.SelectedRow != null) {

        GridViewRow selectedRow = gvDoctorList.SelectedRow;

        Session["PatientId"] = selectedRow.Cells[0].Text;
        Session["firstname"] = selectedRow.Cells[1].Text;
        Session["lastname"] = selectedRow.Cells[2].Text;

        Server.Transfer("Patientstaticformatrix.aspx");
    } else {
        ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Please select a row.')", true);
    }
}

在这里,您位于第一页,并从行中获取数据。然后将此数据存储在会话变量中,您可以使用以下内容在下一页中找到数据:

protected void Page_Load(object sender, EventArgs e) {
    if (this.Page.PreviousPage != null) {
        //Retrieve values from Session Variables
        Response.Write("PatientId: " + Session["PatientId"].ToString() + "<br />");
        Response.Write("firstname: " + Session["firstname"].ToString() + "<br />");
        Response.Write("lastname: " + Session["lastname"].ToString() + "<br />");
    }
}

你还有第二个选项可以使用查询字符串来传递数据。不过,对于这种方法,我相信你需要将Server.Transfer("Patientstaticformatrix.aspx");改为Response.Redirect("Patientstaticformatrix.aspx"); 以下是使用查询字符串的示例:
protected void btnformatric_Click(object sender, EventArgs e) {
    if (gvDoctorList.SelectedRow != null) {
        GridViewRow selectedRow = gvDoctorList.SelectedRow;
        //Create URL with Query strings to redirect to new page
        Response.Redirect("Patientstaticformatrix.aspx?parentid=" + selectedRow.Cells[0].Text + "&firstname=" + selectedRow.Cells[1].Text + "&lastname=" + selectedRow.Cells[2].Text);
    } else {
        ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Please select a row.')", true);
    }
}

在第二个页面中从Request.QueryString对象检索值。

protected void Page_Load(object sender, EventArgs e) {
    if (this.Page.PreviousPage != null) {
        //Retrieve values from Query Strings
        Response.Write("PatientId: " + Request.QueryString["parentid"].ToString() + "<br />");
        Response.Write("firstname: " + Request.QueryString["firstname"].ToString() + "<br />");
        Response.Write("lastname: " + Request.QueryString["lastname"].ToString() + "<br />");
    }
}

这两种解决方案都能满足您的需求,不过它们略有不同。如果需要传递机密信息,建议使用“Session Variable”解决方案,因为它可以防止用户查看所有传递的数据。而“Query String”值对于任何可以看到URL的人都是可用的。
更多关于Session Variables和Query Strings的信息,请参阅以下资源:
ASP.NET会话状态概述
Request.QueryString集合

0

我已经参考了您建议的链接...但在我的情况下,GridView1的名称为gvDoctorList...所以我已经替换了它...但仍然只出现空引用... - Pratik
@Pratik 请看这个链接 http://rajudasa.blogspot.in/2011/08/aspnet-passing-gridview-control-from.html - C Sharper
问题在于,如果页面被移动到主页面或用户控件中,那么这将无法工作。 - Ahmed ilyas
是的,Ahmed,你说得对,我在主页面中有两个页面...所以我正在尝试使用你的rowcommand解决方案...希望它能正常工作。 - Pratik

0
实际上,你应该在另一个页面上创建相同的网格视图。这是99%的ASP.NET站点的工作方式,因为该页面在某个时候会写入/更新/删除数据。或者只需使用同一页 - 为什么要重定向以显示相同的数据呢?

我想从GridView中获取选定的值,并将选定的患者ID插入到SQL表中...但在另一个页面中...因为我想插入患者的图像和当然是患者ID。 - Pratik
那么为什么不在同一页上完成呢? :) - Ahmed ilyas
我在另一个页面配置了相机,所以这就是原因,无法在同一页上实现。 - Pratik
1
我明白了。那很简单。基本上,在这个有网格的页面上,让他们输入/更新详细信息,然后调用数据库,成功后将返回一个ID,将该记录ID传递到下一页进行拍摄,然后在确认后使用该图像更新表格并附带记录ID。 - Ahmed ilyas

0

我找到了一些解决方案:

在 ASPX 源代码中,在网格数据绑定之后:

Session["gridtoexcel"] =  yourgrid;

在目标 aspx 页面中

 var grid = ((GridView)Session["gridtoexcel"]);

            gridToExcel.Columns.Clear();
            foreach (DataControlField col in grid.Columns)
                  gridToExcel.Columns.Add(col);
            
            gridToExcel.DataSource = grid.DataSource;
            gridToExcel.DataBind();

这样我就可以将完全相同的网格“克隆”到另一个页面。如果您需要一些 CSS 样式,请不要忘记在目标页面中添加它们。

PS:gridToExcel 是您的目标网格


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