优化的 ASP.NET DataGrid 排序
通过最小化ViewState和数据库访问来实现优化的DataGrid排序。
引言
典型的 ASP.NET DataGrid
排序涉及数据库访问和在ViewState中保存数据。因此,最小化数据库访问时间和ViewState的大小是实现最佳 DataGrid
排序解决方案的关键。为了最小化数据库访问,将数据源保存在缓存中是一个好的解决方案,这样可以在时间和内存之间取得平衡。为了最小化ViewState,我们可以关闭ViewState。但是,如果禁用ViewState,内置的排序功能将会丢失,因此 DataGrid
排序的优点也会消失,因为我们可能需要提供额外的按钮。本文介绍了一种克服上述不足,实现最佳 DataGrid
排序的方法,以及在保持其功能的同时最小化页面ViewState的方法。
非显示 ASP.NET 按钮
对于 ASP.NET Button
,它有两个重要的属性:Enabled
和 Visible
。通常,另一个样式属性被忽略了。那就是 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);
}
}
接下来是绑定数据。必须在调用 DataGrid
的 DataBind
函数之前调用 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;
}
}
实时演示
您可以下载代码进行试验。