Guide for using GridViews in .Net

Giving it a source of data to display: DataSource property

To make GridViews show some data, you need to feed them with a source with that data first. That source is called DataSource and the GridView has a property to bind it:

gridProducts.DataSource = getSomeSourceFromAroundThere();

The source can be a Data type using ADO like a DataReader or a DataTable in a DataSet, but it can also be a group of objects like an Array of Strings or a Collection (List, Dictionary, …) of objects, even IEnumerables can be used. I’m going to try to show most of the examples using an ADO source and a Collection source:

//Using DataReader
IDataReader rd = MyNamespace.Users.getUsersReader();
gridUsers.DataSource = rd;
gridUsers.DataBind();

//Using ADO DataTable
DataTable tb = MyNamespace.Users.getUsersTable();
gridUsers.DataSource = tb;
gridUsers.DataBind();

//Using a Collection (List<User>)
gridUsers.DataSource = MyNamespace.Users.getUsers(); //This returns a List<Users>
gridUsers.DataBind();

//Using LINQ
gridUsers.DataSource = from u in Users.getUsers() select u;
gridUsers.DataBind();

Notice I’m calling DataBind() all the time. Well, once you have assigned a source of data to the grid, you need to bind them so that the GridView makes the job of getting that data and display it. Just assigning the DataSource is not enough to show the data, only when you call Databind() you are making the call to show it.

Setting the Datasource in the Front End

I don’t really like this method but you can add a SqlDataSource object to your page and use it to link the GridView with some data. This SqlDataSource object can have all type of properties to access the data like a ConnectionString and a SQL query so that it gets the data directly from DB and gives it to the GridView pointing to it:


You can bind more GridViews (or other binding objects) to the same SqlDataSource making it work for all the objects with just one request to the db. Anyway, I don’t like this methodology even if it’s useful in very small projects since it’s not layering the code at all and it’s incredibly risky in my opinion.

You can, also, change the DataSource properties in the BackEnd, or even assign it the data as in the first example with the GridView, but it seems a bit absurd to use a SqlDataSource object when you are setting it in the Backend anyway.

Populating GridView with automatic columns

// To do

Setting GridView columns manually

// To do

Using Column Templates

// To do

Using the RowDataBound event to check rows after being bound

You may find that sometimes its not that direct or easy to get a column value shown in the GridView as you want it, for example, imagine we add a ButtonField and we want to it to be shown as an image that is different depending on the row value (a set ON/OFF button with 2 different images depending on the status).

We could add the OFF button by default in the GridView:

<asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="False" onrowdatabound="gvProducts_RowDataBound">
    <Columns>
    <asp:ButtonField ButtonType="Image" ImageUrl="~/imgs/SellableOff.gif" CommandName="SetSellableON" />
    </Columns>
</asp:GridView>

And now we can replace it by the ON button in run time depending on the item value. We are going to use the GridView’s RowDataBound event for this, so we can check what’s being set to the row when it has just been filled and also the datasource. Being able to access the datasource we can check this:

        protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e) {
            if (e.Row.RowType == DataControlRowType.DataRow) { //Check that its a DataRow and not a Header, Footer, etc.
                //Set sellable btn:
                DataRowView row = e.Row.DataItem as DataRowView;
                if (row["sellable"] != null && (Boolean)row["sellable"] == true) {
                    ((ImageButton)e.Row.Cells[0].Controls[0]).ImageUrl = "~/imgs/buttons/SellableOn.gif";
                    ((ImageButton)e.Row.Cells[0].Controls[0]).CommandName = "SetSellableOFF";
                }
            }
        }

Notice that I’m not only changing the ImageButton source, but also its CommandName so that when you click it I can know which Command the user wants to execute.

Also, notice too that the DataSource was a Datatable with DataRows here so I took it as a DataRowView to access the DataSource data being filled into this row. Now let’s see if I decided to use a collection of one of my class objects (object oriented! always object oriented!):

        protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e) {
            if (e.Row.RowType == DataControlRowType.DataRow) {
                //Set sellable btn:
                Product p = e.Row.DataItem as Product;
                if (p != null && p.IsSellable) {
                    ((ImageButton)e.Row.Cells[5].Controls[0]).ImageUrl = "~/imgs/buttons/SellableOn.gif";
                    ((ImageButton)e.Row.Cells[5].Controls[0]).CommandName = "SetSellableOFF";
                }
            }
        }

Using the RowCommand event to set row actions

// To do

More

Leave a Reply

Close Bitnami banner
Bitnami