Sorting column not working on gridview

854 Views Asked by At

probably this is easy but I am facing troubles to make sort works for a column of a gridview. The idea is to click at column:

<asp:BoundField ItemStyle-Width="150px"  HeaderText="Available Inventory" SortExpression="availInventory" />

So explaining how the gridview is sourced the following columns values are obtain through a sql query consult and they are binded to the gridview: Family, Recipe, Top Part Number, Generic Part Number, Child#1 Part Number, Factor Child1, Child#2 Part Number, Factor Child2, Child#3 Part Number, Factor Child3. The values for columns Attrition, Inventory Child1, Inventory Child2, Inventory Child3 and Available Inventory are calculated at RowDataBound method of the gridview. The gridview is loaded at page after selection of some dropdownlists.

Gridview

        <asp:GridView ID="recipegrid" runat="server" Width="1200px" Height="152px" AutoGenerateColumns="false" AllowSorting="true" OnSorting="recipegrid_Sorting" CssClass="generalgrid" AllowPaging="true" OnPageIndexChanging="OnPaging" PageSize="50" OnRowDataBound="recipegrid_RowDataBound" OnSelectedIndexChanged="recipegrid_SelectedIndexChanged" HeaderStyle-CssClass="gridHeader" RowStyle-CssClass="gridRows" PagerStyle-CssClass="paginationRow" OnDataBound="recipegrid_DataBound"> 
        <Columns>
    <asp:BoundField ItemStyle-Width="150px" DataField="Family" HeaderText="Family" />
    <asp:BoundField ItemStyle-Width="150px" DataField="RecipePN" HeaderText="Recipe" />
    <asp:BoundField ItemStyle-Width="150px" DataField="TopPN" HeaderText="Top Part Number" />
    <asp:BoundField ItemStyle-Width="150px" DataField="GenericPN" HeaderText="Generic Part Number" />
    <asp:BoundField ItemStyle-Width="150px"  HeaderText="Attrition" />
    <asp:BoundField ItemStyle-Width="150px" DataField="Child1PN" HeaderText="Child#1 Part Number" />
    <asp:BoundField ItemStyle-Width="150px" DataField="FactorChild1" HeaderText="Factor Child1" />
    <asp:BoundField ItemStyle-Width="150px"  HeaderText="Inventory Child1" />
    <asp:BoundField ItemStyle-Width="150px" DataField="Child2PN" HeaderText="Child#2 Part Number" />
    <asp:BoundField ItemStyle-Width="150px" DataField="FactorChild2" HeaderText="Factor Child2" />
    <asp:BoundField ItemStyle-Width="150px"  HeaderText="Inventory Child2" />
    <asp:BoundField ItemStyle-Width="150px" DataField="Child3PN" HeaderText="Child#3 Part Number" />
    <asp:BoundField ItemStyle-Width="150px" DataField="FactorChild3" HeaderText="Factor Child3" />
    <asp:BoundField ItemStyle-Width="150px"  HeaderText="Inventory Child3" />
    <asp:BoundField ItemStyle-Width="150px"  HeaderText="Available Inventory" SortExpression="availInventory" />

    <asp:TemplateField HeaderText="Status" Visible="false" ItemStyle-Width="150px">
            <ItemTemplate>
                <asp:Label ID="lblStatus" runat="server"></asp:Label>
            </ItemTemplate>
    </asp:TemplateField>

    <asp:TemplateField HeaderText="Select Data" ItemStyle-Width="150px" >  
                <ItemTemplate>  
                    <asp:RadioButton ID="recipeselector"  runat="server" AutoPostBack="true"  OnCheckedChanged="rbtnSelect_CheckedChanged" />
                   <!-- <asp:HiddenField ID="HiddenField1" runat="server"  /> -->
                </ItemTemplate>  
    </asp:TemplateField>  

        </Columns>
        <EmptyDataTemplate><label class="labelemptygriddata"> No data loaded from DB!</label> </EmptyDataTemplate>
    </asp:GridView> 

sortDirection Method

        private string sortDirectionMethod (SortDirection sortDirection)
    {
        string newSortDirection = String.Empty;

        switch (sortDirection)
        {
            case SortDirection.Ascending:
                newSortDirection = "ASC";
                break;

            case SortDirection.Descending:
                newSortDirection = "DESC";
                break;
        }

        return newSortDirection;
    }

Sorting method

        protected void recipegrid_Sorting(object sender, GridViewSortEventArgs e)
    {

        //DataTable dt = recipegrid.DataSource as DataTable;
        DataTable dt = new DataTable();

        //Session["grid"] = recipegrid.DataSource;


        dt = (DataTable)Session["grid"];


        if (dt != null)
        {
            DataView dv = new DataView(dt);
            dv.Sort = e.SortExpression + " " + sortDirectionMethod(e.SortDirection);

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


    }

So the issue is the sorting is not working as I get the following error:

An exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll but was not handled in user code Additional information: Cannot find column availInventory.

Any help or guidance will be much appreciated. Thanks

EDIT adding code of fetching/storing values of gridview to datatable, which is contained inside RowDataBound Method. The method is too large so I am only posting where I form the datatable and define the session variable:

            //copy info from gridview to session
        //need to add each column name and type
        DataTable dt = new DataTable();
        DataRow dr;
        //Boolean noCheck = false;

        //column Family
        dt.Columns.Add("Family", typeof(string));
        //column Recipe
        dt.Columns.Add("Recipe", typeof(string));
        //column Top Part Number
        dt.Columns.Add("Top Part Number", typeof(string));
        //column Generic Part Number
        dt.Columns.Add("Generic Part Number", typeof(string));
        //column Attrition
        dt.Columns.Add("Attrition", typeof(string));

        //column child#1 Part Number
        dt.Columns.Add("Child#1 Part Number", typeof(string));
        //column Factor Child1
        dt.Columns.Add("Factor Child1", typeof(string));
        //column Inventory Child1
        dt.Columns.Add("Inventory Child1", typeof(string));

        //column Child#2 Part Number
        dt.Columns.Add("Child#2 Part Number", typeof(string));
        //column Factor Child2
        dt.Columns.Add("Factor Child2", typeof(string));
        //column Inventory Child2
        dt.Columns.Add("Inventory Child2", typeof(string));

        //column Child#3 Part Number
        dt.Columns.Add("Child#3 Part Number", typeof(string));
        //column Factor Child3
        dt.Columns.Add("Factor Child3", typeof(string));
        //column Inventory Child3
        dt.Columns.Add("Inventory Child3", typeof(string));

        //column Available Inventory 
        dt.Columns.Add("Available Inventory", typeof(Int32));

        //column select data
        dt.Columns.Add("Select Data", typeof(string));

        foreach (GridViewRow row in recipegrid.Rows)
        {
            System.Web.UI.WebControls.RadioButton selectData = (System.Web.UI.WebControls.RadioButton)row.FindControl("recipeselector");
            dr = dt.NewRow();

            //family
            dr[0] = row.Cells[0].Text;
            //recipe
            dr[1] = row.Cells[1].Text;
            //top partnumber
            dr[2] = row.Cells[2].Text;
            //generic partnumber
            dr[3] = row.Cells[3].Text;
            //attrition
            dr[4] = row.Cells[4].Text;

            //child#1 partnumber
            dr[5] = row.Cells[5].Text;
            //factor child1
            dr[6] = row.Cells[6].Text;
            //inventory child1
            dr[7] = row.Cells[7].Text;

            //child#2 partnumber
            dr[8] = row.Cells[8].Text;
            //factor child2
            dr[9] = row.Cells[9].Text;
            //inventory child2
            dr[10] = row.Cells[10].Text;

            //child#3 partnumber
            dr[11] = row.Cells[11].Text;
            //factor child3
            dr[12] = row.Cells[12].Text;
            //inventory child3
            dr[13] = row.Cells[13].Text;


            //available inventory
            dr[14] = Convert.ToInt32(row.Cells[14].Text);

            //select data
            dr[15] = selectData.Checked = false;

            dt.Rows.Add(dr);
        }
        Session["grid"] = dt;
1

There are 1 best solutions below

0
wazz On

The error is: Cannot find column availInventory.

Your bound field is

<asp:BoundField ItemStyle-Width="150px"  HeaderText="Available Inventory"
    SortExpression="availInventory" />

Try changing the SortExpression to Available Inventory, to match

dt.Columns.Add("Available Inventory", typeof(Int32));.