2008-09-26 32 views
4

我無法讓我的GridView使用戶在使用自定義SqlDataSource時對數據列進行排序。如何使用自定義數據源對ASP.NET GridView中的列進行排序?

我有一個GridView,其中在ASP參考它在HTML代碼是最小的:

<asp:GridView id="grid" runat="server" AutoGenerateColumns="False" AllowSorting="True"> 
</asp:GridView> 

在代碼後面附上一個動態創建的SqlDataSource(它包含的列不總是相同的,所以用於創建它的SQL是在運行時構造的)。例如:

我成立列...

BoundField column = new BoundField(); 
column.DataField = columnName; 
column.HeaderText = "Heading"; 
column.SortExpression = columnName; 

grid.Columns.Add(column); 

數據源...

SqlDataSource dataSource = new SqlDataSource(
    "System.Data.SqlClient", 
    connectionString, 
    generatedSelectCommand); 

然後在GridView ...

grid.DataSource = dataSource; 
grid.DataKeyNames = mylistOfKeys; 
grid.DataBind(); 

在當用戶點擊列標題時,我預計它會對列數據進行排序時,什麼也沒有發生。任何人有任何想法我失蹤?

如果有更好的方法來做到這一點,這也會有幫助,因爲這看起來很亂!

回答

4

首先,你需要添加一個事件:

<asp:GridView AllowSorting="True" OnSorting="gvName_Sorting" ... 

然後該事件是這樣的:

protected void gvName_Sorting(object sender, GridViewSortEventArgs e) 
{ 
    ... 
    //rebind gridview 
} 

基本上,你必須重新獲取數據。

你說得對,它看起來凌亂,有一個更好的辦法:ASP.Net MVC

不幸的是,這是一個顯着不同的頁面模型。

0

我不確定這個,但是如果你使用標準的SqlDataSource並且你點擊一個字段根據這個字段進行排序,那麼SqlDataSource會再次填充數據並且它會被反彈回網格。所以排序不會發生在客戶端,也可以只在SQLDataSource的selectmethod不是DataReader時才能完成。

在處理排序事件時,是否重新創建SqlDataSource並將其重新提交給GridView?你可以把排序字段和方向放到你使用的generatedSelectCommand中嗎?或者把它放到SQLDataSource的SortParameterName屬性?

我絕對相信你必須將SqlDataSource重新彈回到網格,並且由於您在運行中創建它,所以必須重新填充它。

+0

此刻,我根本不處理排序事件,而是將它留給它的默認行爲。但是,我已經檢查過在排序事件中SortExpression和SortDirection是合理的,而不是空白。 數據源在回發後重新綁定到網格, – 2008-09-26 09:57:11

+0

您應該像Keith提到的那樣處理事件。使用標準的SqlDataSource控件它會自動完成,但在這種情況下,您還應該自己處理。 – Biri 2008-09-26 09:59:20

0

比從未更好的遲到?

基思的建議,基本上是正確的一些補充。

事實是,你必須處理gridView_Sorting事件的排序問題。 以前不需要DataBind(),例如在Page_Load事件中。在那裏你應該只調用GridView.Sort()方法而不是.DataBind()。這是怎麼回事:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

    If Not IsPostBack Then 

     Me.gridView.Sort(Request.QueryString("sortExpression"), Request.QueryString("sortDirection")) 

    End If 

End Sub 

接下來讓我們看看gridView_Sorting事件。

在那裏您必須將數據源推送到正確的排序。 GridView本身不處理(至少在這種情況下)。

Protected Sub gridView_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gridView.Sorting 
    If IsPostBack Then 
     e.Cancel = True 
     Dim sortDir As SortDirection = SortDirection.Ascending 
     If e.SortExpression = Me.Q_SortExpression And Me.Q_SortDirection = SortDirection.Ascending Then 
      sortDir = SortDirection.Descending 
     End If 
     RedirectMe(e.SortExpression, sortDir) 
    Else 
     Dim sortExpr As String = e.SortExpression + " " + IIf(e.SortDirection = SortDirection.Ascending, "ASC", "DESC") 
     Dim dv As System.Data.DataView = Me.dsrcView.Select(New DataSourceSelectArguments(sortExpr)) 
     Me.gridView.DataSource = dv 
     Me.gridView.DataBind() 
    End If 
End Sub 

不需要編碼數據源中的任何排序功能,如將排序參數傳遞給存儲過程。所有的排序都在上面的代碼段中進行。

而且,這是很好的有gridView.EnableViewState切換爲False這導致頁面是網絡流量和瀏覽器以及輕得多。可以做到這一點,因爲無論何時頁面被回傳,網格都會被完全重新創建。

有一個愉快的一天!

馬丁

4

你也可以只重新分配在分揀處理程序的DataBind()調用之前的datasource.SelectCommand。像這樣的東西:

protected void gvItems_Sorting(object sender, GridViewSortEventArgs e) 
{ 
    GridView gv = (GridView)sender; 
    SqlDataSource ds = (SqlDataSource)gv.DataSource; 
    ds.SelectCommand = ds.SelectCommand + " order by " 
     + e.SortExpression + " " + GetSortDirection(e.SortDirection); 
    gvItems.DataSource = ds; 
    gvItems.DataBind(); 
} 

string GetSortDirection(string sSortDirCmd) 
{ 
    string sSortDir; 
    if ((SortDirection.Ascending == sSortDirCmd)) 
    { 
     sSortDir = "asc"; 
    } 
    else 
    { 
     sSortDir = "desc"; 
    } 
    return sSortDir; 
} 

我希望這可以幫到你。讓我知道你是否需要額外的幫助來實現它。

享受!

相關問題