SPGridView - Using a custom TemplateField to add a Checkbox Column

Things I cover on this Post:

  • Custom TemplateField/ItemTemplate
  • Custom Paging icons - no code required! (well almost)

Many people out there (Powlo and Jason Wang are great examples) have shown you how to use the SPGridView and do cool things like paging, sorting, filtering etc., but, have you ever wanted to use a column that contains other Controls such as a Checkbox, Textbox or other Controls within your column? 

In this Post, I will show you how you can do just that. I will also mention issues I encountered and how I overcame those. 

Figure 1 - SPGridView with custom TemplateField displaying Checkbox Control and custom paging images  

image 

So let's get started! 

First, if you use the out of the box SPGridView and you add your custom TemplateField Column programmatically or declaratively, then do a PostBack when paging for instance, the first problem you will encounter is that the DataSource is null after the PostBack and you will get the following message: 

Figure 2 - Error when doing a PostBack  
image

After much time spent on this, I found a great post (SPGridView, SPMenuField, Grouping, Postback) covering this exact issue.  So, I did exactly what they suggested, create my own SPGridView by inheriting from the OOTB one, creating my assembly and referencing it on my aspx page.  

By the way, if you try and declaratively (see image below) add a column, you do not clear the columns programmatically (which you probably don't want in this case), you will get another nice message, this post talks about it as well (Grouping in SPGridView

"The Template property must be initialized before rendering 
this control. It cannot be null when the control is rendered. "

FIGURE 3 - Because the SPGridView inherits from the .NET 2.0 GridView, you may think you can do this in a declarative manner, but it is not possible, at least not for getting it to work properly.

image   

Things to keep in mind when working with SPGridView

  1. Always programmatically add your TemplateField column
  2. Make sure you clear the columns
  3. Set the AutoGenerateColumns property to false on the SPGridView


FIGURE 4 - 
Shows how you can programmatically set the SPGridView properties and make sure you clear the columns

clip_image001

  


Great, so how do you get started?

Here are the steps I would take to do this again:

  1. Create your aspx to display your custom SPGridView (this could be a WebPart as well)
  2. At the top of the page, reference your assembly (make sure you have your assembly in the GAC)
  3. Declaratively setup your SPGridView
  4. Write code in the code-behind (typically within the CreateChildControls() method) to setup all properties, add the columns, and call DataBind()

NOTE: I had to make sure the SPDataSource pulled data on the page OnInit, otherwise, you will get an error.

Steps 1 and 2

FIGURE 5 - Registering your custom SPGridView assembly on top of the aspx page

clip_image001[5]


Step 3 
Figure 6 - Declaratively setting some properties (note, you don't need to add columns here, so ignore the TemplateField, we will add it programmatically) 

clip_image001[7]

 

Step 4

 

Below is a piece of code that shows you how you typically add BoundField columns.  The interesting portion is how we will add our custom TemplateField column using your newly created TemplateField Class (I named it CustomSPGridViewTemplate) 

FIGURE 7 - Adding your custom TemplateField column to the grid.

image


Developing the custom TemplateField Class

Here is where the fun begins :)  We are going to create our own TemplateField Class which inherits from ITemplate.  You need to override the InstantiateIn method, and add your code to create the child controls dynamically, in my case, the checkbox.  

It is no fun if you can't bind your dynamically created Controls to some DataSource you are using, so I also created an Event Handler for the DataBinding Event, this is where you will check values and modify the control values conditionally if needed. 

I was able to disable/enable the Checkbox based on some business rules.  I was also able to check it based on some conditions :) All on the DataBinding Event. 

Figure 8 - Shows you my custom TemplateField Class, and how I add my Checkbox Control.  
image


So what is going on here?  One thing I do, is check what the ListItemType we are dealing with (hence the Switch statement), once we get a ListItemType.Item, this is where I want to add my Controls.  

As I already mentioned, one important piece of code to take notice of, is the event handler to handle DataBinding for your dynamically added Control.  This will allow you to bind to a row of data in your DataSource.  In my case, that is the nice SPDataSource set in List Mode :)  See Using SPDataSource below.

 FIGURE 9 - The DataBinding Event Handler for the Checkbox Control

image


The Container for your control will be the SPGridViewRow, therefore, you will be able to access any column values in that row using common methods such as using the DataBinder.Eval and specifying the column name to retrieve the value for :) 

What I am doing above is checking to see the item is required by retrieving the value on the SharePoint List column, if so, disabling it.  Another thing I am doing is checking if I need to set the Checked property to true or false.  In my case, I use the isDeliverableUsedAready custom method that queries my SharePoint List.


Using SPDataSource

Another cool feature of the SPDataSource is the fact that you can use a CAML query (soon I will start using the CAML .NET written by John Holliday) to obtain items from my SharePoint List! This allowed me to manipulate the order the List Items were returned.  Before using the SelectStatement from the SPDataSource, when I grouped my items, for some reason I would find duplicate Groups.  I tried making sure the data was clean, even changed the List View in the SharePoint List and nothing.  It was until I used the SelectStatement and specified the order that grouping worked! In my case, I ordered by the same Field I wanted to group by.  

FIGURE 10 - How my SPDataSource looks on my ASPX page.  
image

 

Enabling paging and using custom paging images

With very little code, you can actually get the paging to look more appealing!  All you have to do is enable paging and specify the images to use based on the Mode you selected.  All this happens within your CreateChildControls where you are setting other properties on your SPGridView 

FIGURE 10 - Enabling paging and specifying custom images

clip_image001[9]

You need to make sure that you set the PagerTemplate to null in order for this to work.  Then specify the PagerSettings.Mode, and finally tell the SPGridView what images you would like to use.  As many of you know, MOSS 2007/WSS 3.0 comes with so many cool little icons and images, so why use anything else? Don't get me wrong, I can get down with creating some images, and doing a little PhotoShop work, but that's another post! 

FIGURE 11 - Where you can find all the nice images used by MOSS/WSS 3.0  

image 

Well, I hope you get some benefit from this post!  If this post has helped you, please drop me a line and let me know, I always welcome constructive criticism as well! 

My next post will be InfoPath 2007 browser based forms - Using Cascading Dropdown Menus


Until next time, 
Oscar



Read more: http://blogs.sharepointace.com/post/SPGridView-Using-a-custom-TemplateField-to-add-a-Checkbox-Column.aspx#ixzz1eQq8GqHw 
Under Creative Commons License: Attribution Non-Commercial Share Alike

posted @ 2011-11-22 19:16  Areas  阅读(761)  评论(0编辑  收藏  举报