DataView 提供了几项用于对 DataTable 中的数据进行排序和筛选的功能:
所以利用 DataView 的特点,我们可以实现 DataGrid 对列的排序。我实现这样一个DataGrid可以点击各个列头,对不同列进行排序。其原理是: 在客户端触发事件提交到服务端,服务端根据不同的列名对同一个DataTable进行操作生成不同的DataView绑定到 DataGrid, 实现排序的效果。
因为表头是我自定义的div, 所以我需要一个隐藏域来区别客户端提交过来的事件。另外我需要一个隐藏域来获得客户端点击的是哪一列。(保存点击的列名)
在aspx页里有如下两个隐藏域:
<input id="command" type="hidden" name="command" runat="server">
<input id="sortCol" type="hidden" name="sortCol" runat="server">
表头设计如下:
<table id="caption" cellSpacing="0" cellPadding="0" width="604" border="1"><tr style="BACKGROUND-COLOR: buttonface">
<td id="tdName" style="CURSOR: hand" onclick="ClickTitle(this)" width="30%" runat="server">Name</td>
<td id="tdTitle" style="CURSOR: hand" onclick="ClickTitle(this)" width="30%" runat="server">Title</td>
<td id="tdTelephone" style="CURSOR: hand" onclick="ClickTitle(this)" width="30%" runat="server">Telepone</td>
</tr></table>
点击表头中各个列头的时候,将触发客户端onclick事件执行客户端脚本ClickTitle()
function ClickTitle(item)
{
item.setAttribute("bgcolor", "#999999", 0);
document.getElementById("command").value = "sort";
document.getElementById("sortCol").value = item.innerText;
document.forms[0].submit();
}
这个方法,将隐藏域command赋值为sort, 同时将被点击的列名保存在隐藏域sortCol中,提交到服务端。
服务端在Page_Load()的方法中处理来自客户端的不同请求。
(为了方便操作,代码里把数据源DataTable,DataView定义为类成员变量)
private void Page_Load(object sender, System.EventArgs e)
{
if(!this.IsPostBack)
{
BindData();
}
if(this.command.Value == "sort")
{
BindData();
// sortedDataView是对DataTable重新排序后的DataView
DataView sortedDataView = new DataView(dt, "", this.sortCol.Value.TrimEnd('5'), DataViewRowState.CurrentRows);
switch(this.sortCol.Value)
{
case "Name":
this.tdName.InnerHtml = "Name<span style='FONT-FAMILY: Marlett;'>5</span>";
this.tdTitle.InnerHtml = "Title";
this.tdTelephone.InnerHtml = "Telephone";
break;
case "Title":
this.tdTitle.InnerHtml = "Title<span style='FONT-FAMILY: Marlett'>5</span>";
this.tdName.InnerHtml = "Name";
this.tdTelephone.InnerHtml = "Telephone";
break;
case "Telephone":
this.tdTelephone.InnerHtml = "Telephone<span style='FONT-FAMILY: Marlett'>5</span>";
this.tdTitle.InnerHtml = "Title";
this.tdName.InnerHtml = "Name";
break;
default:
break;
}
this._MyDataView = sortedDataView;
this.DataGrid1.DataSource = sortedDataView;
this.DataGrid1.DataBind();
this.command.Value = "";
this.sortCol.Value = "";
}
}
每次在排序的时候,数据都需要重新绑定,即调用BindData()方法。
private void BindData()
{
string strConn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";
string strDataSource = Server.MapPath(@"../DB/data.mdb");
strConn = strConn + strDataSource;
OleDbConnection objConn = null;
OleDbDataAdapter objDataAdapter = null;
string strSql = "select Name, Title, Telephone from data";
try
{
objConn = new OleDbConnection(strConn);
objDataAdapter = new OleDbDataAdapter(strSql, objConn);
dt = new DataTable();
objDataAdapter.Fill(dt);
this._MyDataView = dt.DefaultView;
this.DataGrid1.DataSource = this._MyDataView;
this.DataGrid1.DataBind();
}
catch(Exception ex)
{
this.Response.Write(ex.Message);
}
}
注: <span style='FONT-FAMILY: Marlett'>5</span> 是显示在列头里朝上箭头的。所以在调用DataView的构造方法的时候需要去掉多余的这个字符。