2013-04-01 61 views
1

您好我想排序多列在GridView像这里显示 Hierarchical (Multi-column) Sorting for the .net GridView?在Gridview中多列排序?

我做家庭作业 我的aspx看起来像

<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="Default.aspx.cs" Inherits="_Default" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head id="Head1" runat="server"> 
    <title>Multiple sorting with Gridview</title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True" 
      AllowSorting="true" onsorting="GridView1_Sorting" style="margin-right: 541px" 
      Width="873px"> 
     </asp:GridView> 
     <p><asp:Label runat="server" ID="lblSortExpression" /></p> 
    </div> 
    </form> 

</body> 
</html> 

在我Aspx.cs页

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Collections.Specialized; 
using System.Text; 
using System.Web.UI.WebControls; 
using System.Data.SqlClient; 

partial class _Default : System.Web.UI.Page 
{ 

    private ListDictionary m_ldSortExpression; 
    private ListDictionary SortExpressions 
    { 
     get 
     { 
      m_ldSortExpression = (ListDictionary)ViewState["SortExpressions"]; 
      if (m_ldSortExpression == null) 
      { 
       m_ldSortExpression = new ListDictionary(); 
      } 
      return m_ldSortExpression; 
     } 
     set { ViewState["SortExpressions"] = value; } 
    } 

    protected void Page_Load(object sender, System.EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      BindData(); 
     } 
    } 

    public void BindData() 
    { 
     // Usually you would get the data from the database. 
     // To simplify the code, I will just fill a datatable with some standard data. 
     DataTable dt = new DataTable(); 
     dt.Columns.Add("FirstName"); 
     dt.Columns.Add("LastName"); 
     dt.Columns.Add("Age"); 
     dt.Columns.Add("Position"); 

     dt.Rows.Add(new object[] { 
      "1", 
      "2", 
      28, 
      "5" 
     }); 
     dt.Rows.Add(new object[] { 
      "2", 
      "8", 
      31, 
      "2" 
     }); 
     dt.Rows.Add(new object[] { 
      "2", 
      "4", 
      31, 
      "4" 
     }); 
     dt.Rows.Add(new object[] { 
      "3", 
      "7", 
      37, 
      "3" 
     }); 
     dt.Rows.Add(new object[] { 
      "4", 
      "4", 
      40, 
      "1" 
     }); 

     DataView dv = dt.DefaultView; 
     // use a stringbuilder to hold the sortexpression for the dataview 
     StringBuilder sbSortExpression = new StringBuilder(); 
     if (SortExpressions.Count > 0) 
     { 
      string[] myKeys = new string[SortExpressions.Count + 1]; 
      SortExpressions.Keys.CopyTo(myKeys, 0); 
      for (int i = 0; i <= SortExpressions.Count - 1; i++) 
      { 
       sbSortExpression.Append(myKeys[i]); 
       sbSortExpression.Append(" "); 
       sbSortExpression.Append(SortExpressions[myKeys[i]]); 
       if (i != SortExpressions.Count - 1) 
       { 
        sbSortExpression.Append(", "); 
       } 

      } 
      lblSortExpression.Text = sbSortExpression.ToString(); 

      // usually we would send that sort-expression now to SQL via some stored-procedure 
      dv.Sort = sbSortExpression.ToString(); 
     } 
     else 
     { 
      lblSortExpression.Text = string.Empty; 
     } 

     GridView1.DataSource = dv; 
     GridView1.DataBind(); 
     PositionGlyph(GridView1, dv.Sort.ToString(), dt); 


    } 

    private void PositionGlyph(GridView GridView1, string p,DataTable dt) 
    { 
     if ((GridView1.Rows.Count == 0) || (string.IsNullOrEmpty(p))) 
      return; 

     Image glyph = new Image(); 
     glyph.EnableTheming = false; 

     string[] words = p.Split(','); 

     foreach (string word in words) 
     { 
      string[] SortType = word.Split(' '); 
      if (SortType[SortType.Length - 1] == SortOrder.Ascending.ToString().Substring(0, 3).ToUpper()) 
       glyph.ImageUrl = "~/Images/down_arrow.png"; 

      else 
       glyph.ImageUrl = "~/Images/up_arrow.png"; 

      int columnindex = dt.Columns[SortType[SortType.Length - 2].ToString()].Ordinal; 
      GridView1.HeaderRow.Cells[columnindex].Controls.Add(glyph); 
      //for (int x = 0; x < dt.Columns.Count; x++) 
      //{ 
      // if (SortType[SortType.Length - 2].ToString()== dt.Columns[x].ColumnName) 
      // { 
      //  GridView1.HeaderRow.Cells[x].Controls.Add(glyph); 
      //  break; 
      // } 
      //} 

     } 

    } 

    protected void GridView1_Sorting(object sender, System.Web.UI.WebControls.GridViewSortEventArgs e) 
    { 
     m_ldSortExpression = SortExpressions; 

     if (!m_ldSortExpression.Contains(e.SortExpression)) 
     { 
      m_ldSortExpression.Add(e.SortExpression, e.SortDirection.ToString().Replace("Ascending", "ASC").Replace("Descending", "DESC")); 
     } 
     else 
     { 
      // Get sort direction 
      string strSortDirection = m_ldSortExpression[e.SortExpression].ToString(); 
      // Was it ascending? 
      if (strSortDirection == "ASC") 
      { 
       // Yes, so sort in desc 
       m_ldSortExpression[e.SortExpression] = "DESC"; 
      } 
      else if (strSortDirection == "DESC") 
      { 
       // it is descending 
       // remove the sort order 
       m_ldSortExpression.Remove(e.SortExpression); 
      } 
     } 

     SortExpressions = m_ldSortExpression; 
     BindData(); 
    } 
    public _Default() 
    { 
     Load += Page_Load; 
    } 

} 

一切都工作正常,即使多个排序,但排序列标题中的箭头显示不正确。我认为问题是在PositionGlyph Method.Asc或Desc箭头是笑我只想为最后点击的标题显示排序方向。请帮助我一样

+0

为了任何人想在应用程序中使用这种技术,我想指出,ListDictionary类型是一个糟糕的选择,为此目的。它不保证密钥以任何特定的顺序出现,并且对FirstName和LastName进行排序与​​对LastName和FirstName的排序非常不同。 OrderedDictionary将是一个更好的选择。 – Martin

+0

@Martin你会在Ordered字典中使用什么键来使这个工作像OP想要的那样?当然不是列或SortExpression的名称。 – JJS

+0

是的,您使用列名称,就像Rahul所示。请注意,这与列标题文本截然不同 - 它必须是唯一的ID。这段代码可以正常工作,你只需将“ListDictionary”的每一个出现交换为“OrderedDictionary”,以确保它保留了正确的顺序。 – Martin

回答

0

您可以在RowCreated事件中显示gridview列的排序行为的箭头,就像我通常那样这种方式

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) 
{ 
    if (e.Row.RowType == DataControlRowType.Header) 
    { 
     foreach (TableCell tc in e.Row.Cells) 
     { 
      if (tc.HasControls()) 
      { 
       // search for the header link 
       LinkButton lnk = (LinkButton)tc.Controls[0]; 
       if (lnk != null && GridView1.SortExpression == lnk.CommandArgument) 
       { 
        // inizialize a new image 
        System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image(); 
        // setting the dynamically URL of the image 
        img.ImageUrl = "~/img/ico_" + (GridView1.SortDirection == SortDirection.Ascending ? "asc" : "desc") + ".gif"; 
        // adding a space and the image to the header link 
        tc.Controls.Add(new LiteralControl(" ")); 
        tc.Controls.Add(img); 

       } 
      } 
     } 
    } 
} 

也触发什么代码实际上做的是它遍历GridView的标题来搜索一个LinkBut​​ton上上升的形象和

的降序排序顺序(框架创建它只有SortExpression属性被设置)。然后,如果发现LinkBut​​ton的是排序字段,然后它显示的图像输出,这是所有

请参阅本 sample

+0

Ramesh谢谢你的回复。我见过你的样品。对于上面的代码片段,排序工作正常,只是为了显示排序方向。我的意思是所有列的上下箭头 –

0

使用:

DataView m_DataView = new DataView(dt); 
m_DataView.Sort =ColumnName1 + " ASC, " + ColumnName2 + " ASC, " + ColumnName3 + " ASC"; 

希望这有助于。

+0

Ansari排序工作正常,只是想显示所有列中列标题的向上和向下箭头 –