【发布时间】:2017-05-03 23:46:02
【问题描述】:
我正在使用this 示例对从DataTable 加载的GridView 进行排序。我还查看了这个post - 我通过向 DataTable 添加列来使用 sajanyamaha 建议,这时 GridView 的日期列开始以一个特性正确排序。我有 11 列,第一列是重定向到另一个页面的选择命令。我没有绑定字段或模板字段,gridview 是从后面代码中的数据表填充的。
问题是排序和分页在所有列上都可以正常工作,除了 2 个日期列。日期列,ReviewDue 和 SubmittedDate。它们正确排序,但在分页时不保留排序顺序。 GridView 将在每次排序列更改时重置为第 1 页,这会导致用户在对日期列进行排序时永远看不到第 1 页。我试图解决和理解的问题是为什么所有其他列都正常运行但日期列的行为不同?需要什么自定义处理才能使日期列表现得像其他字符串或 int 列?
我用谷歌搜索了很多,但我没有找到任何这种奇怪的东西。
这是我的相关代码。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["SortExpr"] = "EPRID";
ViewState["SortDir"] = " DESC";
if (blnIsAdmin == true || blnIsManager == true)
{
BindData();
}
else
{
//redirect
Response.Redirect("~/ErrorPages/AccessDenied.aspx");
}
}
}
private void BindData()
{
GridView1.DataSource = this.GetData();
GridView1.DataBind();
}
private DataTable GetData()
{
string cmdStr = "SELECT * FROM ….ORDER BY " + ViewState["SortExpr"].ToString() + " " + ViewState["SortDir"].ToString();
DataTable table = new DataTable();
table.Columns.Add("EPRID", typeof(Int32));
table.Columns.Add("FormName", typeof(String));
table.Columns.Add("Name", typeof(String));
table.Columns.Add("Completed", typeof(Boolean));
table.Columns.Add("Sup1", typeof(String));
table.Columns.Add("Sup2", typeof(String));
table.Columns.Add("Sup3", typeof(String));
table.Columns.Add("ReviewDue", typeof(DateTime));
table.Columns.Add("SubmittedDate", typeof(DateTime));
table.Columns.Add("SubmittedBy", typeof(String));
table.Columns.Add("DocID", typeof(Int32));
using (SqlConnection conn = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
cmd.CommandType = CommandType.Text;
//get all EPRs (unfiltered grid)
if (blnIsAdmin == true ")
{
cmdStr = "SELECT * FROM … ORDER BY " + ViewState["SortExpr"].ToString() + " " + ViewState["SortDir"].ToString();
using (SqlDataAdapter da = new SqlDataAdapter(cmdStr, conn))
{
da.Fill(table);
}
}
else if (blnIsManager == true)
{
cmdStr = "SELECT * FROM… WHERE user = @user …ORDER BY " + ViewState["SortExpr"].ToString() + " " + ViewState["SortDir"].ToString();
using (SqlDataAdapter da = new SqlDataAdapter(cmdStr, conn))
{
da.SelectCommand.Parameters.Add(new SqlParameter { ParameterName = "@user", Value = strCurrentUser, SqlDbType = SqlDbType.VarChar, Size = 50 });
da.Fill(table);
}
}
}
}
return table;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
//go to page 1 when sorting
GridView1.PageIndex = 0;
string sortExpression = e.SortExpression;
if (GridViewSortDirection == SortDirection.Ascending)
{
GridViewSortDirection = SortDirection.Descending;
SortGridView(sortExpression, DESCENDING);
ViewState["SortDir"] = " DESC";
}
else
{
GridViewSortDirection = SortDirection.Ascending;
SortGridView(sortExpression, ASCENDING);
ViewState["SortDir"] = " ASC";
}
ViewState["SortExpr"] = sortExpression;
}
private void SortGridView(string sortExpression, string direction)
{
ViewState["SortExpr"] = sortExpression;
ViewState["SortDir"] = direction;
//get unfiltered grid
DataTable dt = GetData();
DataView dv = new DataView(dt);
dv.Sort = sortExpression + direction;
GridView1.DataSource = dv;
GridView1.DataBind();
}
public SortDirection GridViewSortDirection
{
get
{
if (ViewState["sortDirection"] == null)
//ViewState["sortDirection"] = SortDirection.Ascending;
ViewState["sortDirection"] = SortDirection.Descending;
return (SortDirection)ViewState["sortDirection"];
}
set { ViewState["sortDirection"] = value; }
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindData();
}
<asp:GridView ID="GridView1" runat="server"
onselectedindexchanged="GridView1_SelectedIndexChanged"
AllowPaging="True"
AllowSorting="True"
Caption="List of awaiting or completed employee performance reviews"
PageSize="25"
onsorting="GridView1_Sorting"
onpageindexchanging="GridView1_PageIndexChanging"
CellPadding="4"
DataKeyNames="EPRID,DocID"
ForeColor="#333333" GridLines="None"
onrowcommand="GridView1_RowCommand"
onrowdatabound="GridView1_RowDataBound"
onselectedindexchanging="GridView1_SelectedIndexChanging"
CssClass="GridStyle" >
<RowStyle BackColor="#F7F6F3" ForeColor="Black" />
<Columns>
<asp:CommandField ShowSelectButton="True" />
</Columns>
<FooterStyle Font-Bold="True" ForeColor="Black" />
<PagerStyle ForeColor="Black" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="Black" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
</asp:GridView>
【问题讨论】:
-
你为什么要同时在数据库和DataView中排序?任何一个都可以吗?
-
您不需要这样做
DataView dv = new DataView(dt); dv.Sort = sortExpression + direction;,因为您在调用GetDate()时已经对数据进行了排序,并且排序已经在数据库级别完成。 -
你们说得都对,反正当我删除 dv 时,我不需要 DataView(我还在学习),日期列的排序恢复为按月-日排序,而不是按年-月-日排序。我尝试将以下内容放在 RowDataBound() 事件中,但它不会改变行为:
e.Row.Cells[8].Text = Convert.ToDateTime(((DataRowView)e.Row.DataItem)["ReviewDue"]).ToString("d");//s它只是让日期值看起来很漂亮。