65.9K
CodeProject 正在变化。 阅读更多。
Home

优化的 ASP.NET DataGrid 排序

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.42/5 (8投票s)

2004年8月14日

CPOL

2分钟阅读

viewsIcon

154966

downloadIcon

1677

通过最小化ViewState和数据库访问来实现优化的DataGrid排序。

引言

典型的 ASP.NET DataGrid 排序涉及数据库访问和在ViewState中保存数据。因此,最小化数据库访问时间和ViewState的大小是实现最佳 DataGrid 排序解决方案的关键。为了最小化数据库访问,将数据源保存在缓存中是一个好的解决方案,这样可以在时间和内存之间取得平衡。为了最小化ViewState,我们可以关闭ViewState。但是,如果禁用ViewState,内置的排序功能将会丢失,因此 DataGrid 排序的优点也会消失,因为我们可能需要提供额外的按钮。本文介绍了一种克服上述不足,实现最佳 DataGrid 排序的方法,以及在保持其功能的同时最小化页面ViewState的方法。

非显示 ASP.NET 按钮

对于 ASP.NET Button,它有两个重要的属性:EnabledVisible。通常,另一个样式属性被忽略了。那就是 Display。如果 Display 设置为 none,则在浏览时该 Button 将消失。但请注意,它仍然存在于 DHTML 对象模型中,并且像可见按钮一样起作用。我们可以利用这个很好的特性来禁用 DataGrid ViewState。然后使用 JavaScript 将点击事件转移到一个非显示按钮,以触发页面回发。在服务器端该按钮的事件处理程序中,我们可以像在 DataGrid 项目命令事件处理程序中一样执行操作。

实现

为了演示这个想法,将以下代码片段放在 HTML 页面中。请注意,DataGrid ViewState 已被关闭。其中添加了一个非显示按钮。

<asp:datagrid id="dgTest" Runat="server" Width="90%" 
          EnableViewState="False" ShowHeader="True"
          AutoGenerateColumns="False" GridLines="Horizontal" 
          BackColor="lightblue">
    <HeaderStyle Wrap="False" Font-Bold="True" BackColor="#3300cc" 
                          ForeColor="white"></HeaderStyle>
    <AlternatingItemStyle BackColor="LawnGreen"></AlternatingItemStyle>
    <Columns>
      <asp:BoundColumn HeaderText="Last Name" DataField="LastName" 
                          ReadOnly="True"></asp:BoundColumn>
      <asp:BoundColumn HeaderText="First Name" DataField="FirstName" 
                          ReadOnly="True"></asp:BoundColumn>
      <asp:BoundColumn HeaderText="Address" DataField="Address" 
                          ReadOnly="True"></asp:BoundColumn>
      <asp:BoundColumn HeaderText="City" DataField="city" 
                          ReadOnly="True"></asp:BoundColumn>
      <asp:BoundColumn HeaderText="Region" DataField="Region" 
                          ReadOnly="True"></asp:BoundColumn>
      <asp:BoundColumn HeaderText="PostalCode" DataField="PostalCode" 
                          ReadOnly="True"></asp:BoundColumn>
      <asp:BoundColumn HeaderText="Country" DataField="Country" 
                          ReadOnly="True"></asp:BoundColumn>
      <asp:TemplateColumn>
        <HeaderTemplate>
          View Detail
        </HeaderTemplate>
        <HeaderStyle HorizontalAlign="Center"></HeaderStyle>
        <ItemTemplate>
          <asp:LinkButton ID="lnkSelect" Runat="server" 
                    text="Select"></asp:LinkButton>
        </ItemTemplate>
        <ItemStyle HorizontalAlign="Center"></ItemStyle>
      </asp:TemplateColumn>
    </Columns>
</asp:datagrid>
<br>
<asp:Button ID="SortButton" style="DISPLAY:none" Runat="server" 
                                  Text="Sort"></asp:Button>

要将点击事件转移到非显示按钮,请修改标题文本并添加一些 JavaScript,如下所示

private void SetHeadText(SORT_ORDER order)
{
    string headtext = "<a href='#' onclick='javascript:document" + 
            ".getElementById(\"{0}\").click();'> Address</a>";
    if(order == SORT_ORDER.DESC)
    {
        this.dgTest.Columns[this.Col_Address].HeaderText = 
            string.Format(headtext,this.SortButton.ClientID);
    }
    else
    {
        this.dgTest.Columns[this.Col_Address].HeaderText = 
            string.Format(headtext,this.SortButton.ClientID);
    }
}

在按钮事件处理程序中,添加以下代码。排序顺序已保存在页面ViewState中。

private void SortButton_Click(object sender, System.EventArgs e)
{
    SORT_ORDER order = (SORT_ORDER)ViewState[SORTORDER];
    
    if(order == SORT_ORDER.ASC)
    {
        this.BindData(SORT_ORDER.DESC);
    }
    else
    {
        this.BindData(SORT_ORDER.ASC);
    }
}

接下来是绑定数据。必须在调用 DataGridDataBind 函数之前调用 SetHeadText

private void BindData(SORT_ORDER order)
{
    DataView dv = this.GetDataSource().DefaultView;

    if(order == SORT_ORDER.ASC)
    {
        this.SetHeadText(SORT_ORDER.DESC);//for future
        this.ViewState[SORTORDER] = SORT_ORDER.ASC; //for current
        dv.Sort = "Address ASC";
        this.SortLabel.Text = "Current sorting order is ascending";
    }
    else
    {
        this.SetHeadText(SORT_ORDER.ASC);//for future
        this.ViewState[SORTORDER] = SORT_ORDER.DESC; //for current
        dv.Sort = "Address DESC";
        this.SortLabel.Text = "Current sorting order is descending";
    }

    this.dgTest.DataSource = dv;

    dgTest.DataBind();
}

为了最小化数据库访问,我们将数据保存在缓存中。

private DataTable  RetrieveDataFromDB()
{
    string SelectString = "select * from Employees";
    
    DataTable dt = new DataTable();
    using(SqlDataAdapter adpt = new 
          SqlDataAdapter(SelectString,this.NorthWindConnStr ))
    {
        adpt.Fill(dt);
    }

    return dt;
}

private DataTable GetDataSource()
{
    object o;
    o = this.Cache[this.CacheKey];
    if (o != null)
    {
        return (DataTable)o;
    }
    else
    {
        DataTable dt = RetrieveDataFromDB();

        this.Cache.Add(this.CacheKey,dt,null, 
             System.Web.Caching.Cache.NoAbsoluteExpiration, 
             System.TimeSpan.FromMinutes(this.CacheTimeSpan),
             System.Web.Caching.CacheItemPriority.Normal,null);
        return dt;
    }

}

实时演示

您可以下载代码进行试验。

© . All rights reserved.