Where to databind a GridView? Something that bothers me a lot when coding is best practice. I am completely self taught and I find it difficult to know whether I am doing things in the 'right way'.

Let's say I have a Gridview on a page which displays data from the following list:

(from foo in someContext.foobars select foo).ToList


Regardless or how simple or complex the query is, can I just bind the Gridview in the page code behind file as below (in Page.Load or wherever else I want it to run):

gvSomeGridview.DataSource = (from foo in someContext.foobars select foo).ToList();
gvSomeGridview.DataBind();


Or, should I have a class elsewhere that performs the query and returns a list and then bind the Gridview like:

gvSomeGridview.Datasource = helperClass.GetGridviewData
gvSomeGridview.DataBind()


Perhaps go one further and also pass the GridView to the helper class as such:

helperClass.BindGridView(gvSomeGridview)


If I am going to require this list elsewhere in my application or bind a different Gridview with the same data then clearly a class is the way forward, however if I do not, is it fine to just bind the GridView using the query in the code behind as per the first example, or is it recommended to keep all such operations in separate classes regardless?
First, you should separate the UI logic (with terms like GridView, databinding etc.) from the business and/or data logic (with terms like queries, DbContext etc.). So your second approach with a helper class is the more correct approach. In general this kind of helper classes are called the Repository pattern.

You should not pass the UI controls like GridView to your business and/or data logic layer.

About where to put GridView.DataBind() - there are few approaches each useful in certain cases:


Set the .DataSource and call .DataBind() in your Page_Init() method - this way the controls created will not all go in the ViewState. This is not always possible but should be used whenever possible.
Set the .DataSource and call .DataBind() in GridView_PreRender() event - this event is only called when GridView.Visible == true so if you show/hide the grid, you will not end up going for the data if it is not displayed.


Also always experiment if setting EnableViewState=false works for you - since by default GridView will always store everything in the ViewState. If this does not work, you should only call .DataBind() when the data is initially retrieved or the view changed (such as Page.IsPostBack == false or when clicking a search button etc.