69 votes

Tri GridView: SortDirection toujours croissant

J'ai un gridview et j'ai besoin de trier les éléments lorsque l'utilisateur clique sur l'en-tête.
Sa source de données est un objet de la Liste.

Le aspx est définie de cette manière :

<asp:GridView ID="grdHeader" AllowSorting="true" AllowPaging="false" 
    AutoGenerateColumns="false" Width="780" runat="server"  OnSorting="grdHeader_OnSorting" EnableViewState="true">
    <Columns>
        <asp:BoundField DataField="Entitycode" HeaderText="Entity" SortExpression="Entitycode" />
        <asp:BoundField DataField="Statusname" HeaderText="Status" SortExpression="Statusname" />
        <asp:BoundField DataField="Username" HeaderText="User" SortExpression="Username" />
    </Columns>
</asp:GridView>

Le code derrière est définie de cette manière :
La première charge :

protected void btnSearch_Click(object sender, EventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    this.grdHeader.DataSource = items;
    this.grdHeader.DataBind();
}

lorsque l'utilisateur clique sur l'un des en-têtes :

protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, e.SortDirection));
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}

Mon problème est que l'e.SortDirection est toujours Croissant.
J'ai une page web avec un code similaire et il fonctionne bien, l'e.SortDirection alterne entre Ascendant et Descendant.

Qu'ai-je fait de mal ?

52voto

rwo Points 331

Le problème avec Session et Viewstate est que vous devez également garder une trace du contrôle gridview pour lequel SortColumn et Direction est stocké s'il y a plus d'un gridview sur la page.

Une alternative à Session et Viewstate consiste à ajouter 2 attributs à Gridview et à garder une trace de Column et Direction de cette manière.

Voici un exemple:

 private void GridViewSortDirection(GridView g, GridViewSortEventArgs e, out SortDirection d, out string f)
{
    f = e.SortExpression;
    d = e.SortDirection;

    //Check if GridView control has required Attributes
    if (g.Attributes["CurrentSortField"] != null && g.Attributes["CurrentSortDir"] != null)
    {
        if (f == g.Attributes["CurrentSortField"])
        {
            d = SortDirection.Descending;
            if (g.Attributes["CurrentSortDir"] == "ASC")
            {
                d = SortDirection.Ascending;
            }
        }

        g.Attributes["CurrentSortField"] = f;
        g.Attributes["CurrentSortDir"] = (d == SortDirection.Ascending ? "DESC" : "ASC");
    }

}
 

21voto

maxbeaudoin Points 1746

Une solution simple:

 protected SortDirection GetSortDirection(string column)
{
    SortDirection nextDir = SortDirection.Ascending; // Default next sort expression behaviour.
    if (ViewState["sort"] != null && ViewState["sort"].ToString() == column)
    {   // Exists... DESC.
        nextDir = SortDirection.Descending;
        ViewState["sort"] = null;
    }
    else
    {   // Doesn't exists, set ViewState.
        ViewState["sort"] = column;
    }
    return nextDir;
}
 

Tout comme le tri par défaut GridView et léger sur ViewState.

USAGE:

 protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();

    items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, GetSortDirection(e.SortExpression));
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}
 

20voto

Sander Points 9804

Le tri bidirectionnel automatique ne fonctionne qu'avec la source de données SQL. Malheureusement, toute la documentation de MSDN suppose que vous l'utilisez, donc GridView peut devenir un peu frustrant.

Pour ce faire, je surveille moi-même l'ordre. Par exemple:

 	protected void OnSortingResults(object sender, GridViewSortEventArgs e)
	{
		// If we're toggling sort on the same column, we simply toggle the direction. Otherwise, ASC it is.
		// e.SortDirection is useless and unreliable (only works with SQL data source).
		if (_sortBy == e.SortExpression)
			_sortDirection = _sortDirection == SortDirection.Descending ? SortDirection.Ascending : SortDirection.Descending;
		else
			_sortDirection = SortDirection.Ascending;

		_sortBy = e.SortExpression;

		BindResults();
	}
 

15voto

George Points 117

Ce problème est absent non seulement avec les sources de données SQL, mais également avec les sources de données objet. Cependant, lors de la définition dynamique de la source de données dans le code, c'est à ce moment-là que tout va mal. Malheureusement, MSDN est parfois vraiment très pauvre en information. Une simple mention de ce comportement (il ne s’agit pas d’un bogue, mais d’un problème de conception) permettrait de gagner beaucoup de temps. Quoi qu'il en soit, je ne suis pas très enclin à utiliser les variables de session pour cela. Je stocke généralement le sens du tri dans un ViewState.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X