How to search and sort Templatefields on a Gridview?

Asked

Viewed 1,253 times

2

Basically, I have a table (Gridview) on an aspx page whose data are defined by Templatefields. For example:

<asp:GridView runat="server" ID="grdProdutos">
    <Columns>
        <asp:TemplateField HeaderText="Produto">
            <ItemTemplate>
                <asp:Label runat="server" ID="lblProduto" Text='<%# Eval("NomeProduto")%>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Tipo">
            <ItemTemplate>
                <asp:Label runat="server" ID="lblTipo" Text='<%# Eval("TipoProduto")%>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Preço">
            <ItemTemplate>
                <asp:Label runat="server" ID="lblPreco" Text='<%# Eval("PrecoProduto")%>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

The methods used in the Behind code are as follows::

RepositorioProdutos banco = new RepositorioProdutos();

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        CarregarGridView();
    }
}

public void CarregarGridView()
{
    var produtos = banco.ObterProdutos();

    if (produtos != null)
    {
        grdProdutos.DataSource = produtos;
        grdProdutos.DataBind();
    }
    else
    {
        throw new Exception("Nenhum produto encontrado.");
    }
}

I would like to know how I could implement a product search (looking for a term in any field) and how I could implement an ordering by clicking on the name of the column I would like to sort (as in Windows Explorer), without having to re-consult the bank (that is, without having to access the method banco.ObterProdutos() again).

Obs.: for the search, I am considering using a textbox that will be used to enter the keyword of the search, and a button that will trigger the search.

2 answers

4


These are two different questions, in my opinion it is not as simple a task as it seems, so this answer is not intended to be definitive, but just trying to show a starting point.

About the Sorting:

Gridview has an event OnSorting that provides a parameter with a property SortExpression that contains a string normally with the name of the field to be ordered.

It turns out that with Linq we can’t sort the fields from a string, for that we need a System.Dynamic library that allows us to use strings instead of lambda Expressions.

So, install System.Linq.Dynamic library by nuget, then make sure to reference your code:

using System.Linq.Dynamic;

Now change your gridView to accept Sorting:

<asp:GridView ID="grdProdutos" AllowSorting="true" OnSorting="gridView_Sorting" runat="server">

In gridView columns we need to define the Sortexpression that tells by which fields we want to sort:

<asp:TemplateField HeaderText="Produto" SortExpression="Produto">

And in your codebehind:

protected void grdProdutos_Sorting(object sender, GridViewSortEventArgs e)
{
    var gridView = (GridView)sender;

    for (int i = 0; i < gridView.Columns.Count; i++)
        if (gridView.Columns[i].SortExpression == e.SortExpression)
            if (e.SortExpression.EndsWith(" desc"))
                gridView.Columns[i].SortExpression = e.SortExpression.Replace(" desc", "");
            else
                gridView.Columns[i].SortExpression = e.SortExpression + " desc";


    gridView.DataSource = banco.ObterProdutos().OrderBy(e.SortExpression);        
    gridView.DataBind();
}

Remembering that Dynamic Linq works with types IQueryable<T>, so if your method ObterProdutos returns a IEnumerable<T> modify the same, probably avoiding making a call to ToList().

To search you can do with the input and a stop button shoot and use the value of the input to search then set again the DataSource, for example:

gridView.DataSource = banco.ObterProdutos().Where(m => m.Produto.StartsWith(valordoinput);
gridView.DataBind();

The boring part will be keeping the search and the Sort together. You would need to create a method that fetches Sortexpression from each of the gridView columns as well as the search expression that returns a list of products with Where and OrderBy.

  • Seems like that’s the most practical way to do it. I would like to avoid redoing the query, since if I have a very large amount of data, it will take longer for me to do the search and ordering (not so much the search). The alternative would be to use Session or ViewState (which would be an alternative to keep the search and Sort together as well), but keeping a lot of data there would not be very good either.

  • So, keeping in the Viewstate carries the client that can get heavy, keep in Session carries the IIS. I think web projects, different from what would be with desktop, leave these tasks in charge of the SQL server ends up being the less expensive, since the one SGDB is optimized to answer queries.

0

If the Grid is already populated you can use the grid ds itself to resume the information without the need to search again at the base.. I believe this would work..

 IList<seuObj> variavel = this.GridView1.DataSource as IList<seuObj>;

 if (variavel != null){
     GridView1.DataSource = variavel.OrderBy(x => x.campo).ToList();
     GridView1.DataBind();
 }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.