Comment trier les colonnes dans un ASP.NET GridView si vous utilisez un DataSource personnalisé?

StackOverflow https://stackoverflow.com/questions/138412

Question

Je ne parviens pas à utiliser GridView pour permettre à un utilisateur de trier une colonne de données lorsque j'utilise un SqlDataSource personnalisé.

J'ai un GridView dans lequel le code dans la référence ASP au HTML est minimal:

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

Dans le code-behind, j'attache un SqlDataSource créé dynamiquement (les colonnes qu'il contient ne sont pas toujours les mêmes et le code SQL utilisé pour le créer est construit lors de l'exécution). Par exemple:

J'ai configuré les colonnes ...

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

grid.Columns.Add(column);

la source de données ...

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

alors le gridview ...

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

Pour le moment, rien ne se passe lorsqu'un utilisateur clique sur un en-tête de colonne alors que je m'attendais à ce qu'il trie les données de la colonne. Quelqu'un at-il des idées de ce qui me manque?

S'il existe un moyen plus agréable de le faire, cela serait également utile, car cela me semble compliqué!

Était-ce utile?

La solution

Vous devez d’abord ajouter un événement:

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

Cet événement ressemble alors à:

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

Vous devez essentiellement récupérer vos données.

Vous avez raison, cela semble compliqué et il existe un meilleur moyen: ASP.Net MVC

Malheureusement, ce modèle de page est radicalement différent.

Autres conseils

Vous pouvez également simplement réaffecter la commande datasource.SelectCommand avant l'appel DataBind () dans le gestionnaire de tri. Quelque chose comme ça:

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;
}

J'espère que cette aide. Faites-moi savoir si vous avez besoin d'aide supplémentaire pour le mettre en œuvre.

Profitez!

Je ne suis pas sûr de celui-ci, mais si vous utilisez un SqlDataSource standard et que vous cliquez sur un champ pour trier en fonction de ce champ, le SqlDataSource est à nouveau rempli avec les données et rebondi à la grille. Le tri ne se produit donc pas du côté client et ne peut également être effectué que lorsque la méthode de sélection de SQLDataSource n'est pas DataReader.

Lorsque vous gérez l'événement de tri, est-ce que vous recréez le SqlDataSource et le rebondissez au GridView? Pouvez-vous mettre le champ de tri et la direction à la commandes générées SELECT que vous utilisez? Ou placez-le dans la propriété SortParameterName de SQLDataSource?

Je suis absolument sûr que vous devez faire rebondir SqlDataSource sur la grille et, puisque vous le créez à la volée, vous devez le remplir à nouveau.

Mieux vaut tard que jamais?

Quelques ajouts à la suggestion de Keith, qui est fondamentalement la bonne.

La vérité est que vous devez gérer le tri sur un événement gridView_Sorting. Il n’est pas nécessaire d’utiliser DataBind () le GridView plus tôt, par exemple dans l’événement Page_Load. Là, vous ne devriez appeler que la méthode GridView.Sort () au lieu de .DataBind (). Voici comment ça se passe:

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

Regardons ensuite l'événement gridView_Sorting.

Là, vous devez pousser la source de données vers le bon tri. GridView lui-même ne gère pas cela (du moins dans ce cas).

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

Il n'est pas nécessaire de coder une fonctionnalité de tri dans la source de données, par exemple en transmettant les paramètres de tri à la procédure stockée. Tout le tri se fait dans les morceaux de code ci-dessus.

De plus, il est bon d’avoir GrilleView.EnableViewState sur False, ce qui allège beaucoup la page pour le trafic réseau et pour le navigateur. Peut le faire car la grille est entièrement recréée à chaque fois que la page est postée.

Passez une bonne journée!

Martin

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top