2017-05-03 71 views
0

我使用this示例對從DataTable加載的GridView進行排序。我也審查了這個post - 我通過向DataTable添加列來使用sajanyamaha建議,這是當GridView的日期列開始正確排序時的一個特性。我有11列,第一列是一個selectcommand重定向到另一個頁面。我沒有boundfields或模板字段,gridview從代碼後面的數據表中填充。從DataTable填充的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> 
+1

你爲什麼要在數據庫和DataView中進行排序?哪一個會好起來的? – Krishna

+0

你不需要這樣做'DataView dv = new DataView(dt); dv.Sort = sortExpression + direction;'因爲您在調用'GetDate()'時已經對數據進行了排序,並且在數據庫級別進行了排序。 – CodingYoshi

+0

你們都正確我不需要DataView(我仍然在學習),無論如何,當我刪除DV時,日期列的排序會恢復到按月份而不是按年份排序。我嘗試在RowDataBound()事件中放入以下內容,但它不會改變行爲:'e.Row.Cells [8] .Text = Convert.ToDateTime(((DataRowView)e.Row.DataItem)[「ReviewDue」] ).ToString(「d」); // s'它只是使日期值看起來很漂亮。 – Doreen

回答

0

解決!部分問題是在SQL查詢字符串'FROM子句'中使用的SELECT語句,cmdStr(爲了簡潔起見,這些內容沒有包含在我的原始問題中 - 可能是我的第一個錯誤是獲得適當的幫助?)。在視圖SELECT語句中,2分datetime列構建是這樣的:

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

和本來應該簡單地:

,NextReview as ReviewDue 
,SubmittedDate 
,etc... 

(順便說一句它並沒有differnce其標準I使用的,101,110 ,111,112 ...)。此外,DataTable的Add()方法中的相應數據類型應與GetData()中的DateTime相匹配。最後,我加了一個條件,並在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 
     } 

在GridView的_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"); 
       }