About



I am an independent .NET and SharePoint Developer living in The Netherlands. My main focus lies with C# and the .NET Framework but I am also a newbie enthusiast in Ruby and Rails.

View Erik Burger's profile on LinkedIn


MCPD: Enterprise Application Developer

MCTS: WSS 3.0 Application Development


Disclaimer



All opinions expressed in this blog are solely those of the author. You may use all the information provided here but please understand that it is provided "AS IS" and comes with no warranty of any kind.




The SPGridView is one of the most ubiquitous controls used in SharePoint. Every single list in SharePoint (and as we all know there’s lots of those!) uses the SPGridView to display its data in neatly formatted rows. We’re able to sort its data, filter it and click on an item to choose from any options available on that item, amongst other options.

When we build a custom Web Part, we suddenly find ourselves without all that SharePoint goodness. The standard GridView (found in System.Web.UI.WebControls) gives us all the abilities we look for, but it takes a lot of effort to make it look like a SharePoint grid. Luckily, there’s the SPGridView (found in Microsoft.SharePoint.WebControls). It inherits from the GridView so can do whatever the GridView can do. But it does it in style – SharePoint style.

The ASPGridView in action

Getting the SPGridView to look and perform just like the standard SharePoint grids does require some work but with the right choices we can limit this to the absolute minimum. Let’s get started.

To host our SPGridView control we’ll need a basic Web Part skeleton which you can find as part of the files attached to this post. There’s nothing special about it, it serves simply as a place to drop our control. You can of course also use the standard Web Part-User Control pattern.

We’ll use a standard DataTable as the data source for our SPGridView which we’ll bind to an ObjectDataSource (found in System.Web.UI.WebControls). I’ve found the ObjectDataSource easier to use than a DataSet (for example, sorting and paging require no additional code whatsoever) and I haven’t quite had time to dive into using the SPDataSource. Once I have, I’ll be sure to update this post as needed.

Our SelectData method will look as follows:

public DataTable SelectData()
{
    DataTable dataSource = new DataTable();
 
    dataSource.Columns.Add("ID");
    dataSource.Columns.Add("Name");
    dataSource.Columns.Add("Region");
    dataSource.Columns.Add("Total Sales");
 
    dataSource.Rows.Add(1, "J. Smith", "Europe", 10000);
    dataSource.Rows.Add(2, "J. Smith", "North America", 15000);
    dataSource.Rows.Add(3, "J. Smith", "Asia", 5000);
    dataSource.Rows.Add(4, "S. Jones", "Europe", 7000);
    dataSource.Rows.Add(5, "S. Jones", "North America", 30000);
    dataSource.Rows.Add(6, "S. Jones", "Asia", 8700);
    dataSource.Rows.Add(7, "W. Nguyen", "Europe", 3000);
    dataSource.Rows.Add(8, "W. Nguyen", "North America", 50000);
    dataSource.Rows.Add(9, "W. Nguyen", "Asia", 25000);
 
    return dataSource;
}

We’ll be initializing our objects in the CreateChildControls method:

protected sealed override void CreateChildControls()
{
    const string GRIDID = "grid";
    const string DATASOURCEID = "gridDS";
 
    gridDS = new ObjectDataSource();
    gridDS.ID = DATASOURCEID;
    gridDS.SelectMethod = "SelectData";
    gridDS.TypeName = this.GetType().AssemblyQualifiedName;
    gridDS.ObjectCreating += new ObjectDataSourceObjectEventHandler(gridDS_ObjectCreating);
    this.Controls.Add(gridDS);
 
    grid = new SPGridView();
    grid.ID = GRIDID;
    grid.DataSourceID = gridDS.ID;
    grid.AutoGenerateColumns = false;
 
    // Paging
    grid.AllowPaging = true;
    grid.PageSize = 5;
 
    // Sorting
    grid.AllowSorting = true;
 
    this.Controls.Add(grid);
 
    SPGridViewPager pager = new SPGridViewPager();
    pager.GridViewId = grid.ID;
 
    this.Controls.Add(pager);
}

There are a few things to note here. One, I am setting the DataSourceID property of the SPGridView control instead of the DataSource property. This is required to enable filtering later on. I’ve no idea why, but I am grateful to Robert Fridén for figuring this out.

Second, I am setting the TypeName of the ObjectDataSource to the ASPGridView control itself. This allows us to access all the properties of the ASPGridView in our GetDataSource method which will prove useful when we’ll perform data binding against a SPList. It does introduce a problem where the ObjectDataSource “cannot find a non-generic method ‘GetDataSource’ …”. It also introduces a problem with the ObjectDataSource creating a fresh instance of our ASPGridView control, which resets our sorely-needed properties. Fortunately, the fix is surprisingly simple.

When ObjectDataSource creates an instance of the type specified through its TypeName property it raises the ObjectCreating event. In this event, we simply assign our current object instance to the object instance the ObjectDataSource is expecting to use:

private void gridDS_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
    e.ObjectInstance = this;
}

Finally, most blogs will tell you that you need to set the PagerTemplate property of the SPGridView to null. I am using the SPGridViewPager here so we don’t need to. In addition, we get the actual paging behavior used by SharePoint without having to implement any of the Paging events.

If you have read other articles which describe the SPGridView you’ll have noticed that I am not creating the columns for the SPGridView here. I used to until I discovered a strange problem when using more than one ASPGridView on the same page. When I’d set the Visible property of one of the controls to False, the headers of the other control would disappear! To prevent this, I’m generating my columns and performing data binding in the Render method:

protected sealed override void Render(HtmlTextWriter writer)
{
    GenerateColumns();
    grid.DataBind();
    base.Render(writer);
}

And that’s all we need to create a simple SPGridView that supports paging and sorting out-of-the-box.

You can see our progress so far here. Also, you can download the solution I created for this part of the series here. The solution uses the WSPBuilder. To install the demo Web Part, simply build the solution and run the Setup.exe file. Then activate the newly created feature in your SharePoint site and add the Web Part to the page.

I hope this post was useful to you. If so, let me know. If you find that there are things missing, I’d love to hear from you, too.

Erik

References:


10 Responses to “Building A SPGridView Control – Part 1: Introducing the SPGridView”

  1. 1 Josh

    Nice and clean way of SPGridview Usage! Thanks…

    I tried refactoring an old webpart of mine in this fashion. I have a problem though using a custom templatefield that contains a button.

    I added a rowCommand-event handler in the CreateChildControls method just before the Controls.Add(grid) – call. This worked fine in my old implementation, now little devil won’t fire.

    If you have faced this issue before, I would be most grateful if you could give me a hint…

  2. 2 Erik Burger

    Hi Josh,

    Thanks for the compliment, I am glad you liked the article.

    I haven’t faced the particular issue you describe but I have been using TemplateFields in the SPGridView so I might be able to help you out. I’ll try to create your situation, i.e. add a TemplateField containing a button and see if I can get it to work. If you can send me some (snippets of) code you’re using that’d be great, you can send them to burger.erik at gmail dot com.

    Erik

  3. 3 BhakthiL

    Great article…very informative

  4. 4 Clarence

    YOU ARE DA MAN!!! …especially with the SPGridViewPager!!! Thank you!

  5. 5 Erik Burger

    You are very welcome Clarence. I was quite pleased when I found the SPGridViewPager myself as it matches the standard SP look-and-feel better :) Glad you found the post useful.

    Erik

  6. 6 spmikey

    Using SPGridViewPager as you suggest, the SharePoint page number does not render. In this case,
    PagerTemplate == “System.Web.UI.TemplateBuilder”. Any idea why the SharePoint paging is missing?
    (Setting PagerTemplate=null, displays GridView page numbers below the grid as normal).
    Thanks.

  7. 7 Erik Burger

    Hi,

    The SPGridViewPager does not provide page number but row numbers, which is the OOB behaviour of SharePoint which is why I use it. If you use PagerTemplate == null you will get page numbers.

    Maybe I am missing what you are asking. Please let me know if I do so I can try helping out further.

    Regards,

    Erik

  8. 8 Beekermd03

    Great article! Really helped me out with my SPGridView.

    I want to filter a date column, but I want to filter it by years. Possible? I do not want every date showing up in the filter list. Is there a way to fix this?

    Thanks!!

  9. 9 Erik Burger

    Hi Mike,

    Glad it helped you out! I haven’t been able to edit the filter list in the way you propose but it’s a very interesting idea. I’ll be sure to look into it and if I come up with anything I will let you know :)

    Cheers,
    Erik

  1. 1 » SPGridView : Filtering Florent Clairambault

Leave a Reply