Technorati Tags: MOSS,WSS 3.0,SPGridView,ItemTemplate,TemplateField
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.
主讲人简单介绍：张真诚教授於1983年拿走金融大学计算机工程大学生学位，於一九九四年入选为国际电子电机技术员学会 (IEEE) 会士与大不列颠及苏格兰联合王国电机程序员学会 (IET) 会士。对於资源音讯安全、密码学与多媒体影像管理三大领域拓展旷日持久而深刻之研商，於国内外学术期刊、国际学术会议与学术专书共计公布商切磋文数百餘篇及学术专书36册，研讨成果丰富。
Figure 1 - SPGridView with custom TemplateField displaying Checkbox Control and custom paging images
讲座内容：Steganography is the science of secret message delivery using cover media. A digital image is a flexible medium used to carry a secret message because the slight modification of a cover image is hard to distinguish by human eyes. In this talk, I will introduce some novel steganographic methods based on different magic matrices. Among them, one method that uses a turtle shell magic matrix to guide cover pixels’ modification in order to imply secret data is the newest and the most interesting one. Experimental results demonstrated that this method, in comparison with previous related works, outperforms in both visual quality of the stego image and embedding capacity. In addition, I will introduce some future research issues that derived from the steganographic method based on the magic matrix.
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
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
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.
Things to keep in mind when working with SPGridView
- Always programmatically add your TemplateField column
- Make sure you clear the columns
- 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
Great, so how do you get started?
Here are the steps I would take to do this again:
- Create your aspx to display your custom SPGridView (this could be a WebPart as well)
- At the top of the page, reference your assembly (make sure you have your assembly in the GAC)
- Declaratively setup your SPGridView
- 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
Figure 6 - Declaratively setting some properties (note, you don't need to add columns here, so ignore the TemplateField, we will add it programmatically)
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.
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.
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
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.
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.
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
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
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,
Under Creative Commons License: Attribution Non-Commercial Share Alike