Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 3 down vote accepted

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:

  1. 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.
  2. 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.

share|improve this answer

Well,

The GridView is an implementation, Down the line if you decide to swap the GridView for a listview or something it should have no bearing on the data.

Exactly how to go about sharing the information is subjective. there is no right way.

My personal preference is a super contracted approach via interfaces. e.g:

public interface FooView
{
   IEnumberable<Foobar> Foobars { set; }

   FooPresenter Presenter { set; }

   void ShowView();
}


public interface FooPresenter
{
  void DisplayFoos();
  void StartApplication();

}

Now i imagine the above doesn't really give much detail but it outlines the vaguest contract between whatever visual representation you choose and the source of the data. In this manner if either change the other is perfectly fine.

As for an example implementation of the above:

    public class GridFooView : FooView
    {
      public FooPresenter Presenter { private get; set; }


      public IEnumerable<Foobar> Foobars
      {
        get{ return _foobars; }
        set
        {
          _foobars = value;
          UpdateFoobarGrid(); //Do binding here
        } 
      }


      void Button_ShowFoo_Clicked(object sender,Eventargs e)
      {
         Presenter.DisplayFoos();
      }


      private IEnumerable<Foobar> _foobars;
    }



public class FooPresenterImpl : FooPresenter
{

   FooView _view;

   public FooPresenterImpl(FooView view)
   {
     if(view == null) throw new NullArgumentException("view")
     _view = view;
     _view.Presenter = this;
   }


   void DisplayFoos()
   {
    //generate your data then pass it to the view who updates himself.
    // the example i have here includes another abstraction of a datamodel.
     _view.Foobars = someDataModel.GetFoos();
   }

   void StartApplication()
  {
    //Do prerequisites
    _view.ShowView(); 
  }


}

Now finally in your program run file you simple instantiate the Presenter of choice, with the view of choice and run startApplication().

FooPresenter presenter = new FooPresenterImpl(new GridFooView());
presenter.StartApplication();

So now if you decide to completely change how Foo's are delivered to the UI, replace the presenter but all views still work, want to make a different representation of the same data? make a new view object, finally your presenter could also contain a datamodel which could be swapped out between storage methods, different database's or config files or we service or whatever.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.