web-dev-qa-db-fra.com

trier et paginer avec gridview asp.net

J'essaie d'obtenir un gridview pour trier et page manuellement, sans succès.

Le problème est que lorsqu'un utilisateur clique sur la colonne qu'il souhaite trier, il trie cette page, mais ne trie pas la source de données (affichage de données) derrière la vue en grille. Ainsi, lorsqu'ils passent à une page différente, leur type est perdu. En gros, je suis à la recherche d’un type qui triera la source de données située derrière la vue en grille. Voici ce que j'ai jusqu'à présent:

protected void GridView_OnSort(object sender, GridViewSortEventArgs e)
    {
        String sortExpression = e.SortExpression;

        if (GridViewSortDirection == SortDirection.Ascending)
        {
            DataView myDataView = new DataView(mybll.GetItemsOrdered());
            myDataView.Sort = sortExpression + " DESC";
            GridView.DataSource = myDataView;
            GridView.DataBind();
        }
        else
        {
            DataView myDataView = new DataView(mybll.GetItemsOrdered());
            myDataView.Sort = sortExpression + " ASC";
            GridView.DataSource = myDataView;
            GridView.DataBind();
        }
    }

Toute aide serait appréciée. Merci.

29
dangerisgo

Enregistrez votre ordre de tri dans un ViewState.

private const string ASCENDING = " ASC";
private const string DESCENDING = " DESC";

public SortDirection GridViewSortDirection
{
    get
    {
        if (ViewState["sortDirection"] == null)
            ViewState["sortDirection"] = SortDirection.Ascending;

        return (SortDirection) ViewState["sortDirection"];                
    }
    set { ViewState["sortDirection"] = value; } 
}

protected void GridView_Sorting(object sender, GridViewSortEventArgs e)
{
    string sortExpression = e.SortExpression;

    if (GridViewSortDirection == SortDirection.Ascending)
    {
        GridViewSortDirection = SortDirection.Descending;
        SortGridView(sortExpression, DESCENDING);
    }
    else
    {
        GridViewSortDirection = SortDirection.Ascending;
        SortGridView(sortExpression, ASCENDING); 
    }   

}

private void SortGridView(string sortExpression,string direction)
{
    //  You can cache the DataTable for improving performance
    DataTable dt = GetData().Tables[0]; 

    DataView dv = new DataView(dt); 
    dv.Sort = sortExpression + direction;         

    GridView1.DataSource = dv;
    GridView1.DataBind();         
}

Pourquoi vous ne voulez pas utiliser la fonctionnalité de tri existante? Vous pouvez toujours le personnaliser.

Tri des données dans un contrôle de serveur Web GridView sur MSDN

Voici un exemple de personnalisation: 

http://www.netomatix.com/development/GridViewSorting.aspx

53
Konstantin Tarkus
<asp:GridView 
    ID="GridView1" runat="server" AutoGenerateColumns="false" AllowSorting="True" onsorting="GridView1_Sorting" EnableViewState="true"> 
    <Columns>
        <asp:BoundField DataField="bookid" HeaderText="BOOK ID"SortExpression="bookid"  />
        <asp:BoundField DataField="bookname" HeaderText="BOOK NAME" />
        <asp:BoundField DataField="writer" HeaderText="WRITER" />
        <asp:BoundField DataField="totalbook" HeaderText="TOTALBOOK" SortExpression="totalbook"  />
        <asp:BoundField DataField="availablebook" HeaderText="AVAILABLE BOOK" />
    </Columns>
</asp:GridView>

Code derrière: 

protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            string query = "SELECT * FROM book";
            DataTable DT = new DataTable();
            SqlDataAdapter DA = new SqlDataAdapter(query, sqlCon);
            DA.Fill(DT);

            GridView1.DataSource = DT;
            GridView1.DataBind();
        }
    }

    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e) {

        string query = "SELECT * FROM book";
        DataTable DT = new DataTable();
        SqlDataAdapter DA = new SqlDataAdapter(query, sqlCon);
        DA.Fill(DT);

        GridView1.DataSource = DT;
        GridView1.DataBind();

        if (DT != null) {
            DataView dataView = new DataView(DT);
            dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);

            GridView1.DataSource = dataView;
            GridView1.DataBind();
        }
    }

    private string GridViewSortDirection {
        get { return ViewState["SortDirection"] as string ?? "DESC"; }
        set { ViewState["SortDirection"] = value; }
    }

    private string ConvertSortDirectionToSql(SortDirection sortDirection) {
        switch (GridViewSortDirection) {
            case "ASC":
                GridViewSortDirection = "DESC";
                break;

            case "DESC":
                GridViewSortDirection = "ASC";
                break;
        }

        return GridViewSortDirection;
    }
}
5
AVIK GHOSH

La réponse de Tarkus fonctionne bien. Cependant, je suggérerais de remplacer VIEWSTATE par SESSION. 

VIEWSTATE de la page en cours ne fonctionne que lorsque celle-ci est postée sur elle-même. Elle disparaît dès que l'utilisateur est redirigé vers une autre page. SESSION maintient l'ordre de tri sur plus que le post-retour de la page actuelle. Il persiste pendant toute la durée de la session. Cela signifie que l'utilisateur peut naviguer vers d'autres pages et lorsqu'il revient à la page donnée, l'ordre de tri qu'il a utilisé en dernier demeure. Ceci est généralement plus pratique. 

Il existe également d'autres méthodes, telles que la persistance de profils d'utilisateurs.

Je recommande cet article pour une très bonne explication de ViewState et de son fonctionnement avec le cycle de vie d'une page Web: https://msdn.Microsoft.com/en-us/library/ms972976.aspx

Pour comprendre la différence entre VIEWSTATE, SESSION et d’autres moyens de persister les variables, je vous recommande cet article: https://msdn.Microsoft.com/en-us/library/75x4ha6s.aspx

0
Jeff Matthews

J'ai trouvé un moyen beaucoup plus simple, qui vous permet de continuer à utiliser le tri/la pagination intégrés de la grille standard ...

créer 2 étiquettes. définissez-les pour qu'ils soient visibles = faux. J'ai appelé le mien lblSort1 et lblSortDirection1

puis code 2 événements simples ... le tri de page, qui écrit dans le texte des étiquettes invisibles, et l'index de page qui change, qui les utilise ...

Private Sub gridview_Sorting(sender As Object, e As GridViewSortEventArgs) Handles gridview.Sorting
lblSort1.Text = e.SortExpression
lblSortDirection1.Text = e.SortDirection
End Sub

Private Sub gridview_PageIndexChanging(sender As Object, e As GridViewPageEventArgs) Handles gridview.PageIndexChanging
    gridview.Sort(lblSort1.Text, CInt(lblSortDirection1.Text))
End Sub

c'est un peu plus compliqué que d'utiliser des variables globales, mais j'ai découvert avec asp surtout que les variables globales sont, eh bien, peu fiables ...

0
Jon

Manière plus simple ...:

    Dim dt As DataTable = DirectCast(GridView1.DataSource, DataTable)
    Dim dv As New DataView(dt)

    If GridView1.Attributes("dir") = SortDirection.Ascending Then
        dv.Sort = e.SortExpression & " DESC" 
        GridView1.Attributes("dir") = SortDirection.Descending

    Else
        GridView1.Attributes("dir") = SortDirection.Ascending
        dv.Sort = e.SortExpression & " ASC"

    End If

    GridView1.DataSource = dv
    GridView1.DataBind()
0
Ranjeet