Geeks With Blogs
christopher w davis
GridViews and SharePoint
Programming for SharePoint poses some challenges to the .NET developer. Of course first you should be familiar with .NET, I will be using c# in my examples here. One of the main development paths for SharePoint is to create modular functionality in Web Parts. Web Parts are great little chunks of a web page that you can cram anything you can think of into; however you won’t have the nice visual tools you are used to working with. For a simple “Hello World” type application this is fine, but what if you want to do something more complicated like say, display a GridView on your page. And what if that GridView got its data from a web service which requires custom column handling based on the DataSet returned? This could actually be a lot of fun, let’s get started.
Your Toolbox
If you are going to be a SharePoint developer you will need a sandbox to experiment with. I like to use a virtual server with Windows 2003 Server, MOSS 2007, Visual Studio 2008, and the SharePoint Visual Studio extensions. Having the virtual server is great for development just in case something goes completely haywire with the deployment of something; I can simply roll back the entire server. Having Visual Studio 2008 on there with the SharePoint extensions makes life easy because it allows us to debug through the web part within the context of SharePoint. It also handles deployment for us so we don’t have to worry about copying manifest files around or registering things in the GAC, all that is taken care of for us by Visual Studio. You can download the SharePoint extensions here:
VMware Player is a great product that I use for loading my Virtual Server, you can find that here:
When you get VMware up and running you will have to create a new virtual environment with Windows Server 2003, MOSS 2007, SQL Server 2005, Visual Studio 2008, and the SharePoint Visual Studio Extensions. Of course you will have to have your own installation disks and serial numbers. Whew, once you have that you’re finally ready to go.
Start Programming
So you want a dynamic GridView in a WebPart that get’s it’s data from a Web Service? Let’s ride! The first thing you’ll have to do is get into your development environment and fire up Visual Studio. If everything is installed correctly then if you create a new project you will see the SharePoint templates in your New Project Dialog:
New Project Dialog
Click on the Web Part Template to create a new Web Part. Can they make it any easier? There is even a TODO statement that tells you where to write code – wow. I remember the days when you had to write everything in a text editor while walking uphill in the snow barefoot; no more!
Once we have a web part we want to delete the default WebPart folder that is added to the project; I guess you could rename it but chances are you will miss a reference or something somewhere, you are just better off deleting and starting over. Once WebPart1 is gone right click on the project and add a new item – you want to add a new Web Part under SharePoint. I named mine GridFromService. Once you have your web part let’s get our web service in there.  
Adding a Service
Right click on services, select Add Service Reference and you will get the following dialog:
Add a service dialog
Put the URL to your reference in here, I have mine installed on a server locally on the network. Notice I am adding a service reference rather than a web reference; you may need to go into advanced->web reference to make sure you get the dialog to add a web reference. I will go into Web References vs. Service References in a different post, stay tuned!
Now that you have the reference in the solution you still have to add the reference into the web.config for SharePoint; remember that SharePoint is an ASP.NET application that already has a lot of configuration, since this part will run within that context we have to make sure that appropriate configuration files are updated. You can find the web.config for SharePoint at the following address: C:\Inetpub\wwwroot\wss\VirtualDirectories\80
Once you have it open, put the following code under the <configuration> node:
 <system.serviceModel>
    <client>
      <endpointname="LoggerService.LoggerSoap"address="http://mddev02:1005/Logger.asmx"binding="basicHttpBinding"contract="LoggerService.LoggerSoap" />
    </client>
    <bindings>
      <basicHttpBinding />
    </bindings>
 </system.serviceModel>
 <system.web>
 
LoggerService.LoggerSoapClient logView = new GridFromServicePart.LoggerService.LoggerSoapClient();
 
DataSet ds = logView.GetEvents(3);
 
Building the GridView
Ok, we have our web reference; we can get data, now we need to display it. I plan on getting back a bunch of data from this web service, but the columns may change over time. I only want to write this thing once so I am going to make it as flexible as possible by generating the columns at run time. Sounds easy right? I just have to make sure autogeneratecolumns is set to true…except there is a catch. Every time there is a date field I need to do something different. In part 2 of this I will add a different context menu based on this condition using JavaScript, for now I’ll just display the date as a short date time string. To accomplish special column handling in pure code I will need to write classes for each column type I want to create. In this case I will just make 2, a text column and a date time column.
When a GridView renders its columns is uses templates to decide how to display those columns. The visual designer in Visual Studio makes this very easy- lots of clicking and dragging things around. Since we don’t have that luxury here we will have to write it ourselves. Each column type will need its own class which implements the ITemplate Interface. I created 2 classes in a separate folder called ColumnTemplates in my solution. At this point you have all the files and references you need to make this work and your solution should look something like this:
Solution Snapshot
Now to create those column classes. The class that implements the ITemplate interface will be where you build a cell in your GridView. The method you will need to override is:  InstantiateIn(System.Web.UI.Control container). This method will be called when the data is being bound to the grid, so you will add your code here to put all the elements you need in the cell and do whatever you need to with your data. I created a few extra methods to help me out later on, here is what the DateTimeColumn looks like:
 
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
 
namespace GridFromServicePart.ColumnTemplates
{
    public class DateTimeColumn : ITemplate
    {
        private string fieldName;
        private bool editMode;
 
        ///<summary>
        /// The DateTime column will handle special conditons when we are
        /// displaying a date in a grid
        ///</summary>
        ///<param name="FieldName"></param>
        ///<param name="inEditMode"></param>
        public DateTimeColumn(string FieldName, Boolean inEditMode)
        {
            fieldName = FieldName;
            editMode = inEditMode;
        }
 
        ///<summary>
        /// this runs when the databound event is called on the grid
        ///</summary>
        ///<param name="container"></param>
        public void InstantiateIn(System.Web.UI.Control container)
        {
            TextBox tb = new TextBox();
            container.Controls.Add(tb);
            tb.DataBinding += new EventHandler(BindText);
            tb.Width = Unit.Pixel(90);
            tb.ID = "txt" + fieldName;
 
            Label lbl = new Label();
            container.Controls.Add(lbl);
            lbl.DataBinding += new EventHandler(BindLabel);
            lbl.ID = "lbl" + fieldName;
            //we will use the following line in part 2...
            //lbl.Attributes.Add("oncontextmenu", "ContextMouseDown(this)");
 
            //if the user is editing the grid
            if (editMode)
            {
                tb.Visible = true;
                lbl.Visible = false;
            }
            else
            {
                tb.Visible = false;
                lbl.Visible = true;
            }
        }
 
        ///<summary>
        /// this binds the data to the control and converts the date time to a short date time string
        ///</summary>
        ///<param name="sender"></param>
        ///<param name="e"></param>
        public void BindText(object sender, EventArgs e)
        {
            TextBox tb = sender as TextBox;
            GridViewRow gvRow = (GridViewRow)tb.NamingContainer;
            DataRowView dRow = (DataRowView)gvRow.DataItem;
 
            object dataValue = DataBinder.Eval(gvRow.DataItem, fieldName);
            DateTime dtVal;
            if (DateTime.TryParse(dataValue.ToString(), out dtVal))
            {
                tb.Text = Convert.ToDateTime(dataValue).ToShortDateString();
            }
            else
            {
                tb.Text = "";
            }
           
            tb.Text = ((DateTime)dataValue).ToShortDateString();
        }
 
        ///<summary>
        /// essentially the same as BindText ecept we are binding a label
        ///</summary>
        ///<param name="sender"></param>
        ///<param name="e"></param>
        public void BindLabel(object sender, EventArgs e)
        {
            Label lbl = sender as Label;
            GridViewRow gvRow = (GridViewRow)lbl.NamingContainer;
            DataRowView dRow = (DataRowView)gvRow.DataItem;
 
            object dataValue = DataBinder.Eval(gvRow.DataItem, fieldName);
            DateTime dtVal;
            if (DateTime.TryParse(dataValue.ToString(), out dtVal))
            {
                lbl.Text = Convert.ToDateTime(dataValue).ToShortDateString();
            }
            else
            {
                lbl.Text = "";
            }
        }
    }
}
 
Notice how there is a text box and a label.  This is to accommodate the edit mode of the grid.    I’m not actually using it here but we will need this in later modifications to the project.
The Finish Line
 
Once you are done with that we can deploy our solution, since we’ve come a long way let’s do that now. You can right-click on the solution or just hit F5, Visual Studio will compile and deploy you’re solution for you. Thanks Microsoft! If everything went smoothly you should have something like this:
 
Grid snapshot
 
Yea its ugly, we will make it pretty later. If something went wrong then you will have to debug this to see what did go wrong. That brings us to the following section:
 
Debugging
 
This probably warrants its own blog entry but I can go clean that up later. To debug through your application you are going to want to go to debug->attach to process. In this dialog you want to select the w3wp.exe process like this:
Attach to process : w3wp.exe
 
Now you can step through the application to see how everything is working.
 
Summary
 
As you can see making highly customized GridViews are certainly very possible even without the nice graphical editor that Visual Studio provides. Using GridViews in SharePoint is an excellent way to display data but certainly doesn’t have to be scary. Using the ITemplate interface is a great way to dynamically create columns without a graphical editor, this will also give you more control over the grid based on the data that is returned.
 
In Part 2 we will discuss adding the JavaScript into the solution to add a context menu into the grid. Thanks for reading, see you next time :^)
Posted on Thursday, October 16, 2008 10:29 AM SharePoint , .NET | Back to top


Comments on this post: Dynamic GridViews with ITemplate and Services in SharePoint

# re: Dynamic GridViews with ITemplate and Services in SharePoint
Requesting Gravatar...
Excellent stuff, this is going to cover just what I need to know. The problem is, I need parts 2, 3, 4 etc now......
Left by Excellent work, where's the rest on Nov 16, 2008 2:11 PM

Your comment:
 (will show your gravatar)


Copyright © cdavis | Powered by: GeeksWithBlogs.net