【问题标题】:binding datatable to grid view将数据表绑定到网格视图
【发布时间】:2011-01-01 09:16:44
【问题描述】:

我有以下代码:

Imports System.Data

Partial Class Students_AddWishes Inherits System.Web.UI.Page

    Public dt As New DataTable

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        dt.Columns.Add("ID", System.Type.GetType("System.Int32"))
        dt.Columns.Add("univirsity", System.Type.GetType("System.Int32"))
        dt.Columns.Add("major", System.Type.GetType("System.Int32"))
    End Sub

    Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        Dim row1 As DataRow = dt.NewRow()
        row1("ID") = dt.Rows.Count + 1
        row1("univirsity") = ddlUnivs.SelectedValue
        row1("major") = ddlMajors.SelectedValue
        dt.Rows.Add(row1)
        GridView1.DataSource = dt
        GridView1.DataBind()
    End Sub

End Class

问题是它只显示一行或记录。如何让它显示多条记录?

【问题讨论】:

    标签: asp.net gridview binding datatable


    【解决方案1】:

    你的页面加载事件你没有检查它是否是回发:

     If Not IsPostBack Then
         'process code if it is not a post back
     End If
    

    每次单击 btnAdd 按钮时,您的页面都会向服务器发送回帖。

    我刚刚注意到您可能不了解对象的生命周期。

    你已经在你的代码中这样做了:

    Public dt As New DataTable 
    

    问题在于你已经定义了这是一个类变量,一旦页面加载,你就有了一个 dt 类型的实例,它可能有一些与之关联的列。但是,一旦您记录了诸如单击按钮之类的事件,该引用就会被销毁并创建一个新的 dt。

    您将不得不使用会话变量或数据库来存储 dt 的状态。

    这是一个 C# 示例:

     protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("ID", System.Type.GetType("System.Int32"));
                dt.Columns.Add("univirsity", System.Type.GetType("System.Int32"));
                dt.Columns.Add("major", System.Type.GetType("System.Int32"));
                Session["MyDataTable"] = dt;
            }
        }
    
        protected void btnAdd_Click(object sender, EventArgs e)
        {
            DataTable t = (DataTable)Session["MyDataTable"];
            DataRow row1 = t.NewRow();
    
            row1["ID"] = t.Rows.Count + 1;
            row1["univirsity"] = 3;
            row1["major"] = 31;
            t.Rows.Add(row1);
    
            Session["MyDataTable"] = t;
            GridView1.DataSource = t;
            GridView1.DataBind(); 
        }
    

    和 vb.net 中相同的代码:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) 
        If Not Page.IsPostBack Then 
            Dim dt As New DataTable() 
            dt.Columns.Add("ID", System.Type.[GetType]("System.Int32")) 
            dt.Columns.Add("univirsity", System.Type.[GetType]("System.Int32")) 
            dt.Columns.Add("major", System.Type.[GetType]("System.Int32")) 
            Session("MyDataTable") = dt 
        End If 
    End Sub 
    
    Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As EventArgs) 
        Dim t As DataTable = DirectCast(Session("MyDataTable"), DataTable) 
        Dim row1 As DataRow = t.NewRow() 
    
        row1("ID") = t.Rows.Count + 1 
        row1("univirsity") = 3 
        row1("major") = 31 
        t.Rows.Add(row1) 
    
        Session("MyDataTable") = t 
        GridView1.DataSource = t 
        GridView1.DataBind() 
    End Sub 
    

    所以现在代码所做的就是实例化一个新的数据表对象,只要我们在页面上(第一次回发)并添加列。一旦它定义了数据表,我们就将它置于某个会话状态。当您单击添加按钮时,您不能在之前的代码中继续使用 dt,因为 dt 范围在您之前的代码中丢失了。我们通过分配在临时数据表之前存储的会话数据表来做到这一点。我们添加行并以这种方式重置会话,下次添加行时,它将显示第二行,然后是第三行,依此类推...

    我推荐一本很好的 asp.net 书籍,例如在 C# 2008 中开始 ASP.net 3.5。有大量关于同一主题的 vb.net 书籍。

    【讨论】:

    • 如何在上述场景中按列显示网格视图
    【解决方案2】:

    您需要将数据表保存到 Session,因为不保留局部变量。所以你需要这样做:

    protected override OnLoad(..) //or OnInit
    {
       dt = Session["DataTable"] as DataTable;
       if (dt == null)
       {
           dt = new DataTable();
           //load columns
       }
    }
    
    protected override OnUnLoad(..)
    {
       Session["DataTable"] = dt;
    }
    

    由于 web 是无状态的,Session 跨回发保存数据表引用。

    【讨论】:

    • 我不会在 Session 中存储 DataTable,因为您基本上是将其存储在服务器的内存中。如果您的应用程序在多个服务器之间进行负载平衡,会发生什么情况?如果表增长到大于 x 行数,或者您的用户数超过了现在的数量,会发生什么情况?
    • 这也是 JonH 的解决方案所做的;您必须将其存储在某处,或者在每次页面加载时从数据库中重新加载;不幸的是,全局变量不保留它的任何值,所以它基本上每次都会丢失......但是从数据库加载或使用缓存或其他数据存储(磁盘 io,如 XMl 文件)也是可行的选择......会话不是唯一的解决方案,只是一个经常选择的解决方案,因为它是用户特定的。你是对的,多台服务器也是一个问题......所以你必须找出正确的解决方案。
    • @dustinupdyke - 这个特定示例将其存储在会话中没有任何问题。我假设您阅读了这个非常基本的问题。当然,如果您的应用程序要进行负载平衡,这本身就是一个完全不同的问题。可以编写自己的自定义缓存机制。最后,您必须知道选择什么。这篇文章的发起者并没有寻找任何高水平的东西,在这种情况下会话工作得很好。
    • @JonH 我读了这个问题,谢谢。我的观点是,如果他们只知道这些例子,那么这些例子就会成为他们的基准。在大多数生产环境中,您不会使用 Session,那么为什么要通过示例来宣传它的使用呢?
    • @dustinupdyke - 我们运行了大量使用会话的生产应用程序,这没有任何意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多