Developing SharePoint 2007 Web Parts
Web Parts are the building blocks of pages in SharePoint sites. Users of SharePoint sites can make use of those building blocks to determine what should be displayed on a specific page in a particular SharePoint site.
When you install SharePoint, you can make use of some out-of-the-box Web Parts straight away. Depending on whether you have Windows SharePoint Services (WSS) or Microsoft Office SharePoint Server (MOSS) as your SharePoint installation, you'll have more or less. Additionally, every SharePoint list and document library will have a Web Part counterpart that can display the contents of the corresponding list or document library.
Of course, the out-of-the-box Web Parts are not the only ones that you can use! Developers can build their own Web Parts as well and deploy them to the SharePoint server. End users won't notice the difference between the custom Web Parts and the out-of-the-box Web Parts, so Web Parts are a great way to extend SharePoint.
This article takes you through the basic steps to create your own Web Parts in various ways.
TIP
The techniques and technologies described in this article are applicable both to Windows SharePoint Services (WSS) and Microsoft Office SharePoint Server (MOSS), unless mentioned otherwise. So, in this article, mention of SharePoint should be interpreted as Windows SharePoint Services 3.0 orMicrosoft Office SharePoint Server 2007.
TIP
Although you can create Web Parts making use of the SharePoint 2003 classes, and use those Web Parts in SharePoint 2007 sites, you should make use of ASP.NET 2.0 Web Parts for your new projects.
Writing the Code
A Web Part in code is just a normal .NET class, nothing more, nothing less. In Visual Studio, you can make use of the Class Library project template to write code for the Web Part class. This code will be compiled into a .NET assembly, in this case a DLL that is exactly what you need. When Visual Studio is started, create a new project and select the Class Library template (Figure 1). The name of the new project is important, so think carefully when you choose a project name. Your project name should be unique on the server on which you would like to deploy your Web Parts. Additionally, the project name will be used later when the Web Parts are deployed. Also, be aware that names in .NET are case-sensitive!
Figure 1: Selecting the Class Library template
TIP
A common practice to ensure unique names in .NET environments is using namespaces. If the project name is, for example, MVP.Book.WebParts
, by default, all the code will be sitting in the namespace with exactly the same name.
Every Class Library project in Visual Studio can contain any number of Web Part classes, so think of the project as the container of your Web Parts.
When the new project is created, there will be one class already available: Class1.cs
. In general,Class1
is not a good name for a Web Part, so rename the class to HelloWorld
. The special thing about a Web Part class is the fact that the class inherits from a specific base WebPart
class. This base WebPart
class is available in the System.Web
assembly (Figure 2). By default, the Class Library project doesn't contain a reference to this assembly, so you should add it yourself. Right-click the project node in the Solutions Explorer window and choose Add Reference. Next, select theSystem.Web
assembly from the list.
Figure 2: Locating the
System.Web
assemblyNow the HelloWorld
class can inherit from the WebPart
that is available in theSystem.Web.UI.WebControls.WebParts
namespace class.
TIP
To avoid having to type the full namespace of the WebPart
base class (and other classes as well), it's a common practice to add using
statements on top of your code. In this article, the common namespaces won't be prefixed.
The resulting code is probably the most basic Web Part that can be created. It's a Web Part that doesn't do anything. But because the HelloWorld
class inherited from the base WebPart
class, the HelloWorld Web Part already has a title bar and a border, as shown in Figure 3.
Figure 2: HelloWorld Web Part with title bar and border
TIP
All Web Part classes must be scoped public
. A Web Part class that is not marked as public
can't be used in SharePoint Web Part pages. In C#, when a new Class Library project is created, the default class Class1
is automatically set to the public
scope. Unfortunately, classes that are added to the project are not scoped public
automatically; the developer must add the public
keyword manually!
A Web Part developer must only focus on what should happen inside the Web Part. The contents displayed inside the Web Part should be generated in the Render
method of the Web Part class. This method is already implemented in the base WebPart
class, so it should be overridden in the HelloWorld WebPart
class. This is the default implementation:
protected override void Render(System.Web.UI.HtmlTextWriter writer) { base.Render(writer); }
The only parameter of the Render
method is the writer
parameter, which is of the typeHtmlTextWriter
. You should use this parameter to write HTML that will be rendered inside the Web Part. It's important to write valid HTML with the writer
parameter, because invalid HTML is accepted as well, so it could break the Web Part page. The HelloWorld Web Part should display fixed text, which is formatted as a title:
protected override void Render(System.Web.UI.HtmlTextWriter writer) { writer.Write("Web Parts Rock!
"); }
TIP
It's not recommended to write HTML tags in plain strings as displayed in the previous example. Later in this article, I discuss the proper way to generate HTML. The purpose of this example is to show the real basics.
For now, the code is sufficient. It is a Web Part that displays fixed text. Before you can deploy this Web Part, the project must be built. So, the assembly (DLL) is generated. There are many ways to trigger the build process in Visual Studio, such as with the Build menu, using the Ctrl+Shift+B key combination, and so on.
The complete contents of the Class1.cs
looks like this:
using System; using System.Collections.Generic; using System.Text; using System.Web.UI.WebControls.WebParts; namespace BasicWebParts { public class HelloWorld: WebPart { protected override void Render( System.Web.UI.HtmlTextWriter writer) { writer.Write("Web Parts Rock!
"); } } }
Using Controls in Web Parts
In the previous HelloWorld Web Part example, the Web Part code generated HTML by using a string. It is quite obvious that generating HTML for more complex user interfaces can be complicated. This section examines using controls in Web Parts to simplify the generation of HTML code in Web Parts:
The .NET Framework has lots of Web controls that can be used in Web Parts, including Button
,Textbox
, Label
, and so on. Most of those user controls are residing in theSystem.Web.UI.WebControls
namespace. The advantage of these ASP.NET Web controls is that they can generate HTML for themselves. You as a developer don't have to focus on writing HTML to render a button, for example.
Simple Calculator Example
To illustrate the use of Web controls in Web Parts, let's write a very basic example that nicely shows how to make use of a couple of Web controls, including server-side code for the event handlers of those controls. The example used will be a basic Calculator Web Part: just two textboxes for entering two numeric values, two buttons for adding and subtracting those values, and a third textbox to display the result. The focus of this Web Part won't be how to validate the entered values, and so on, but rather to just show how to build the user interface and the server-side code.
Getting Started with the SimpleCalculator Class
A Web Part using Web controls is still a normal Web Part. So, in the BasicWebParts
Visual Studio project, add another class named SimpleCalculator
. First, add the following using
statements on top of the code:
using System.Web.UI.WebControls.WebParts; using System.Web.UI.WebControls; using System.Web.UI;
The using
statements allow you to make use of the WebPart
base class and all the ASP.NET Web controls without including the full namespace.
The second (and very important) addition to the code that must be made is the public keyword for theSimpleCalculator
class. By default, in a Visual Studio 2005 C# Class Library project, the Class template doesn't include the public keyword. If the Web Part class doesn't have this public keyword, SharePoint won't be able to make use of it, so it must be added. The complete SimpleCalculator
class looks like this now:
using System; using System.Collections.Generic; using System.Text; using System.Web.UI.WebControls.WebParts; using System.Web.UI.WebControls; using System.Web.UI; namespace BasicWebParts { public class SimpleCalculator: WebPart { } }
Declaring the Web Control Variables
For every Web control on the Web Part, a variable of that Web control should be declared as a member field. For the sample SimpleCalculator Web Part, there must be five variables registered (three textboxes and two buttons):
public class SimpleCalculator: WebPart { TextBox tbA; TextBox tbB; TextBox tbResult; Button btnAdd; Button btnSub; }
Overriding the CreateChildControls Method
The next step to build the SimpleCalculator Web Part is to override the CreateChildControls
method from the base WebPart
class. In this method, you first create of all new instances for all the Web control variables. Additionally, properties for those Web controls can be set as well. Lastly, all the Web control instances should be added to the Controls
collection of the base WebPart
class so that ASP.NET knows about them, and, thus, the server-side events (if they exist) will be handled correctly. Of course, it doesn't matter where the variables are instantiated and added in theCreateChildControls
method. It can be in the beginning, but it can be at the end as well; they can be added even dynamically in code. Personally, I prefer to structure my code as displayed here:
protected override void CreateChildControls() { tbA = new TextBox(); tbB = new TextBox(); tbResult = new TextBox(); btnAdd = new Button(); btnSub = new Button(); tbResult.ReadOnly = true; btnAdd.Text = "+"; btnSub.Text = "-"; this.Controls.Add(tbA); this.Controls.Add(tbB); this.Controls.Add(btnAdd); this.Controls.Add(btnSub); this.Controls.Add(tbResult); }
In the SimpleCalculator Web Part example, the ReadOnly
property for the results textbox is set to true
, so end users won't be able to change anything in that textbox. This is done from code. Also the text properties of the buttons are set to "+"
and "-"
.
The order in which the controls are added to the Controls
collection of the base WebPart
class will determine how they are rendered later on in the Web Part. For this example, the two input textboxes should be rendered first, the two operation buttons should be rendered second, and, finally, the textbox that should display the result should be rendered.
If the controls are added like this, one after another, all of them will appear on one line. If the controls should be displayed on multiple lines, HTML break tags (
) can be added in between, as shown here:
this.Controls.Add(tbA); this.Controls.Add(new LiteralControl("
")); this.Controls.Add(tbB); this.Controls.Add(new LiteralControl("
")); this.Controls.Add(btnAdd); this.Controls.Add(btnSub); this.Controls.Add(new LiteralControl("
")); this.Controls.Add(tbResult);
Alternatively, HTML tables, layers, and so on can be used as a more flexible way to add layout to the Web Part.
Adding Event Handlers
At this point, the code doesn't do anything except render some Web controls. The goal, of course, is to execute code when one of the operation buttons is clicked. This can be accomplished by adding event handlers for the corresponding events. These event handlers can be added in theCreateChildControls
method as well.
btnAdd.Click += new EventHandler(btnAdd_Click); btnSub.Click += new EventHandler(btnSub_Click);
The implementation of the event handlers can be done as follows. The btnAdd_Click
andbtnSub_Click
methods are members of the SimpleCalculator
class as well.
void btnAdd_Click(object sender, EventArgs e) { int a = int.Parse(tbA.Text); int b = int.Parse(tbB.Text); int c = a + b; tbResult.Text = c.ToString(); } void btnSub_Click(object sender, EventArgs e) { int a = int.Parse(tbA.Text); int b = int.Parse(tbB.Text); int c = a - b; tbResult.Text = c.ToString(); }
TIP
Once again, the focus of this Web Part is not on how to validate the input of the textboxes before the calculations are done. When this code is used in a real-life scenario, adding validation code is obviously required.
The Full SimpleCalculator Code
Now, the SimpleCalculator
class is finished, and the complete combined code could look as follows:
using System; using System.Collections.Generic; using System.Text; using System.Web.UI.WebControls.WebParts; using System.Web.UI.WebControls; using System.Web.UI; namespace BasicWebParts { public class SimpleCalculator: WebPart { TextBox tbA; TextBox tbB; TextBox tbResult; Button btnAdd; Button btnSub; protected override void CreateChildControls() { tbA = new TextBox(); tbB = new TextBox(); tbResult = new TextBox(); btnAdd = new Button(); btnSub = new Button(); tbResult.ReadOnly = true; btnAdd.Text = "+"; btnSub.Text = "-"; btnAdd.Click += new EventHandler(btnAdd_Click); btnSub.Click += new EventHandler(btnSub_Click); this.Controls.Add(tbA); this.Controls.Add(new LiteralControl("
")); this.Controls.Add(tbB); this.Controls.Add(new LiteralControl("
")); this.Controls.Add(btnAdd); this.Controls.Add(btnSub); this.Controls.Add(new LiteralControl("
")); this.Controls.Add(tbResult); } void btnAdd_Click(object sender, EventArgs e) { int a = int.Parse(tbA.Text); int b = int.Parse(tbB.Text); int c = a + b; tbResult.Text = c.ToString(); } void btnSub_Click(object sender, EventArgs e) { int a = int.Parse(tbA.Text); int b = int.Parse(tbB.Text); int c = a - b; tbResult.Text = c.ToString(); } } }
The SimpleCalculator looks like Figure 4 at run-time.
Figure 4: SimpleCalculator Web Part
Manually Rendering the Web Controls
The user controls of the SimpleCalculator Web Part are rendered automatically on the Web Part's user interface because the default implementation of the Render
method renders all items in the Control
collection of the base WebPart
class. It's also possible to override this method so that you are in full control of the rendering process. For every Web control, the RenderControl
method can be called to render the corresponding HTML.
protected override void Render(HtmlTextWriter writer) { this.EnsureChildControls(); tbA.RenderControl(writer); writer.Write("
"); tbB.RenderControl(writer); writer.Write("
"); btnAdd.RenderControl(writer); btnSub.RenderControl(writer); writer.Write("
"); tbResult.RenderControl(writer); }
If the preceding code is used, the HTML break tags don't have to be added to the Controls
collection. The CreateChildControls
method could look as follows:
protected override void CreateChildControls() { tbA = new TextBox(); tbB = new TextBox(); tbResult = new TextBox(); btnAdd = new Button(); btnSub = new Button(); tbResult.ReadOnly = true; btnAdd.Text = "+"; btnSub.Text = "-"; btnAdd.Click += new EventHandler(btnAdd_Click); btnSub.Click += new EventHandler(btnSub_Click); this.Controls.Add(tbA); this.Controls.Add(tbB); this.Controls.Add(btnAdd); this.Controls.Add(btnSub); this.Controls.Add(tbResult); }
No comments:
Post a Comment