3

I want to sort my GridView in the CodeBehind but my sorting methode give me an infinite loop.

My GridView, for testing, look like:

<asp:GridView ID="GVEquipe" OnRowDataBound="GVEquipe_RowDataBound"  OnSorting="GridView_Sorting"    AllowSorting="true" AutoGenerateColumns="False" DataKeyNames="Employee" runat="server">
<Columns>
    <asp:HyperLinkField DataTextField="Employee" DataNavigateUrlFields="Employee" DataNavigateUrlFormatString="~/Profil.aspx?No_Emp={0}" HeaderText="No d'employé" SortExpression="Employee" />
    <asp:BoundField DataField="FirstName" HeaderText="Prénom" SortExpression="FirstName" />
    <asp:BoundField DataField="Name" HeaderText="Nom" SortExpression="Name" />
    <asp:BoundField DataField="Machine" HeaderText="Machine" SortExpression="Machine" />
    <asp:TemplateField HeaderText="Infractions" SortExpression="Alerte">
        <ItemTemplate>
            <asp:ImageButton ID="IBAlerte" runat="server" ImageUrl='<%# Convert.ToDouble(Eval("Alerte")) >= 5d ? "~/Images/alerte3.PNG" : Convert.ToDouble(Eval("Alerte")) < 3d ? "~/Images/alerte0.PNG" : "~/Images/alerte2.PNG" %>' CommandArgument='<%# Bind("Employee") %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Événements" >
        <ItemTemplate>
            <asp:ImageButton ID="IBDelai" ImageUrl="~/Images/loupe.png" runat="server" />
        </ItemTemplate>
    </asp:TemplateField>
</Columns>

I Generate the DataSource in the Page_Load.

My sorting method is:

    protected void GridView_Sorting(object sender, GridViewSortEventArgs e)
    {
        GridView gv = (GridView)sender;            
        gv.Sort(e.SortExpression, e.SortDirection);
    }

I Made it generic because I'll use it for the other GridView in the same page.

EDIT: I change a lot of thing and now it's work.

protected void GridView_Sorting(object sender, GridViewSortEventArgs e)
{
    sortDirection = e.SortDirection;
    GridView gv = (GridView)sender;
    if (gv.ID == "GVEquipe")
        equipeColumnToSort = e.SortExpression;
    DataSource();
}

I use local variable such as:

Finally, in the end of my DataSource() method, I order my DataSource (of type IEnumerable):

if (!String.IsNullOrEmpty(equipeColumnToSort))
{
    switch (equipeColumnToSort)
    {
        case "Employee":
            listEquipes = listEquipes.OrderBy(x => x.Employee);
            break;
        case "FirstName":
            listEquipes = listEquipes.OrderBy(x => x.FirstName);
            break;
        case "Name":
            listEquipes = listEquipes.OrderBy(x => x.Name);
            break;
        case "Machine":
            listEquipes = listEquipes.OrderBy(x => x.Machine);
            break;
        case "Alerte":
            listEquipes = listEquipes.OrderBy(x => x.Alerte);
            break;
    }
    if (sortDirection == SortDirection.Descending)
        listEquipes = listEquipes.Reverse();                
}
Félix LD
  • 366
  • 1
  • 5
  • 19

1 Answers1

0

You shouldn't call Sort from inside that event, since it indeed will go in an infinite loop.

What you should do is handle the sorting. When you look at the sample at MSDN, you will see you have to sort the data set behind your grid view.

If you have a DataTable for example, you should sort it something like this:

DataTable dt; // define your data table

dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GVEquipe.DataSource = dt;
GVEquipe.DataBind();
Patrick Hofman
  • 143,714
  • 19
  • 222
  • 294
  • @felix: need more help? – Patrick Hofman May 26 '15 at 13:01
  • What is the issue with it? – Patrick Hofman May 26 '15 at 13:10
  • I have some difficulty for setting the DataTable. I do : "DataTable dt = Session["TaskTable"] as DataTable;" And i set the session in the method for generate the DataSource like: "Session["TaskTable"] = GVEquipe.DataSource;" But When The method exit the Session is lost: "+ base {"Impossible d'accéder à un objet supprimé.\r\nNom de l'objet : 'Accès à DataContext après Dispose.'."} System.InvalidOperationException {System.ObjectDisposedException}" – Félix LD May 26 '15 at 13:14
  • You should show your entire code. I think you can access chat now, so let's see if you can put it in there. (Eh, no you can't. Not enough rep for chat... Can you post a new question with the code?) – Patrick Hofman May 26 '15 at 13:16
  • Sorry, you can't yet since you don't have enough rep. I would post a new question to fix that issue with your code. – Patrick Hofman May 26 '15 at 14:14
  • Is there a way for define my DataTable from my DataSource ? Following your link, I'm setting the Session like : "Session["TaskTable"] = dataSourceEquipe.Cast().ToList();" Then, I try to create a DataTable with my session: "DataTable dt = (DataTable) Session["TaskTable"];" And I'm getting an error with the cast : "Impossible d'effectuer un cast d'un objet de type 'System.Collections.Generic.List`1[System.Object]' en type 'System.Data.DataTable'." – Félix LD May 26 '15 at 14:23
  • You should create a `DataTable` first in your `Page_Load` like in the sample, and that one you should save in the session or so (maybe reinitialize it every time, I don't know which is best). – Patrick Hofman May 26 '15 at 14:25
  • Would you give me an exemple for create a DataTable? Because the sample doesn't create it dynamically. – Félix LD May 26 '15 at 14:37
  • Sure, this one covers most of your question I think http://stackoverflow.com/a/4089514/993547. (So open a connection to your database, execute the command, and fill the datatable) – Patrick Hofman May 26 '15 at 14:40
  • I don't use DataReader, my DataSource is set using LINQ. – Félix LD May 26 '15 at 14:56