【问题标题】:Date columns will not sort on Gridview filled from DataTable日期列不会在从 DataTable 填充的 Gridview 上排序
【发布时间】: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 它只是让日期值看起来很漂亮。

标签: c# .net-3.5


【解决方案1】:

解决了!部分问题在于 Sql 查询字符串的 FROM 子句中使用的视图中的 SELECT 语句 cmdStr (为简洁起见,我最初的问题中省略了这些细节 - 可能是我在获得适当帮助时的第一个错误?)。在视图的SELECT 语句中,2 个日期时间列的构造如下:

,Convert(varchar(10),NextReview,112) as ReviewDue
,Convert(varchar(10),SubmittedDate,112) as SubmittedDate 

应该是:

,NextReview as ReviewDue
,SubmittedDate
,etc...

(顺便说一句,我使用的标准没有区别,101、110、111、112...)。此外,DataTable 的 Add() 方法中的相应数据类型应匹配为 DateTimein GetData()。最后我添加了一个条件,将SQL内联查询中的ORDER BY子句cmdStr修改为:

//pass ViewState to variable for use in cmdStr when DateTime columns are sorted on
    strExpression = ViewState["SortExpr"].ToString();

        if (strExpression == "ReviewDue" || strExpression == "SubmittedDate")
            {
             cmdStr = "SELECT * FROM vwView ORDER BY CONVERT(DATE, " + strExpression + ", 120) " + ViewState["SortDir"].ToString();  
            } 

        else
        {
        //use original cmdStr
        }

在 gridviews _RowDataBound() 事件中,我还将日期格式化为仅在网格中显示日期部分,如下所示:

//ReviewDue will never be null
        e.Row.Cells[8].Text = Convert.ToDateTime(((DataRowView)e.Row.DataItem)["ReviewDue"]).ToString("d");

                //SubmittedDate can be null, handle null 
                object dtmDate9 = ((DataRowView)e.Row.DataItem)["SubmittedDate"];

                if (dtmDate9 == DBNull.Value)
                {
                    e.Row.Cells[9].Text = String.Empty;
                }
                else
                {

                    e.Row.Cells[9].Text = Convert.ToDateTime(((DataRowView)e.Row.DataItem)["SubmittedDate"]).ToString("d");
                }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-07
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 2018-09-06
    相关资源
    最近更新 更多