Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Summary: Learn to create a custom Web Part for Microsoft Office Project Server 2007 that you can use to display the upcoming tasks for a specified project.
**Applies to:**2007 Microsoft Office system, Project Server 2007
Joel Krist, Akona Systems
September 2007
![]() A Web Part is a modular unit of information that has a single purpose and is a basic building block of a Web Part Page. Project Web Access uses many Microsoft Office Project Server 2007 Web Parts and can be easily extended with custom Web Parts. Web Parts in Windows SharePoint Services 3.0 improve upon earlier versions of Web Part technologies. You can use Windows SharePoint Services 2.0 Web Parts and ASP.NET 2.0 Web Parts. You can also use Web Parts in shared Web Part Page documents in a project workspace or team site. The shared documents are stored and managed on a computer running Windows SharePoint Services that is provisioned by Project Server. This Office Visual How To article shows the creation of a custom Web Part for Project Server 2007 that you can use to display the upcoming tasks for a specified project. The code presented in this article is based on the "No PWA Reference" Web Part sample that is included in the Microsoft Office Project 2007 SDK download. |
![]() ![]() Length: 00:11:01 | Size: 17.2 MB | Type: WMV file |
Code It | Read It | Explore It
This section walks through the six major steps to create a Web Part for Project Server 2007. The key steps are:
Creating a Web Control Library project in Microsoft Visual Studio 2005.
Adding the required references.
Setting the Web Part assembly version number.
Signing the Web Part assembly with a strong name.
Adding the code that implements the functionality of the Web Part that displays upcoming tasks for a specified project.
Deploying the Web Part.
The following section shows how to create a Web Control library project.
Start Visual Studio.
On the File menu, point to New, and then click Project.
In the New Project dialog box, in the Project Types pane, select Visual C# or Visual Basic, and then select the Windows category.
In the Templates pane, select Web Control Library.
Type ProjectServerWebParts for the project Name.
Specify a location for the project, and then click OK. Visual Studio generates a Web Control Library project with a single source file in it named WebCustomControl1.cs or WebCustomControl1.vb, depending on which language you selected in Step 3.
Right-click the file in Solution Explorer, and then choose Rename. Rename the WebCustomControl1.cs or WebCustomControl1.vb source file to UpcomingTasksWebPart.cs or UpcomingTasksWebPart.vb, depending on which language you are using.
To derive a class that implements the Upcoming Tasks Web Part from the Microsoft.SharePoint.WebPartPages.WebPart class, you need to add a reference to the Windows SharePoint Services assembly.
If you are running Visual Studio on a computer that has Windows SharePoint Services or Microsoft Office SharePoint Server 2007 installed on it, use the following procedure:
On the Visual Studio Project menu, click Add Reference.
In the Add Reference dialog box, on the .NET tab, locate and select the Windows SharePoint Services component (Microsoft.SharePoint.dll).
Click OK to add the reference.
If you are running Visual Studio on a computer that does not have Windows SharePoint Services or Office SharePoint Server installed on it, the Windows SharePoint Services assembly is not available. In this case:
Copy the Microsoft.SharePoint.dll assembly file from a computer that has Windows SharePoint Services or Office SharePoint Server installed on it to a local project folder on the development computer. Following is the default assembly location on a SharePoint server:
%ProgramFiles%\Common Files\Microsoft Shared\Web server extensions\12\ISAPI
After you make a local copy of the assembly, add a reference to it by browsing for the local file as follows:
On the Visual Studio Project menu, click Add Reference.
In the Add Reference dialog box, on the Browse tab, navigate to the local folder containing the copy of the Windows SharePoint Services assembly.
Select the Microsoft.SharePoint.dll file, and then click OK to add the reference.
The Upcoming Tasks Web Part uses the Project Server Interface (PSI) to integrate with Project Web Access. The PSI is a Web service interface that enables client applications—including Microsoft Office Project Professional 2007, Project Web Access, and back-end line-of-business applications—to access Project Server data.
To allow the Upcoming Tasks Web Part to work with the PSI, add a reference to the Project Web service. A client locates a Web service and obtains its service description by Web service discovery. The process of Web service discovery in Visual Studio involves interrogating a Web site to locate the service description, which is an XML document that uses the Web Services Description Language (WSDL). When you add a Web reference to a project, Visual Studio generates a proxy class that provides a local representation of the Web service, and allows the client code to interface with the Web service. You access methods of the Web service by calling the methods in the proxy class. The proxy class handles the communication between the client application and the Web service.
In Visual Studio Solution Explorer, right-click the ProjectServerWebParts project, and then click Add Web Reference.
In the Add Web Reference dialog box, type the URL of the Project Web service. Following is the default location of the Web service: http://ServerName/ProjectServerName/_vti_bin/PSI/project.asmx.
Click Go. Visual Studio retrieves and displays the information about the Web service.
Type ProjectWS for the Web reference name, and then click Add Reference to add the Web reference to the project. Visual Studio downloads the service description and generates a proxy class to interface between the Upcoming Tasks Web Part and the Project Web service.
Figure 1. Adding Web reference
By default, the AssemblyVersion property of the Upcoming Tasks Web Part project is set to increment each time the Web Part is recompiled. A SharePoint Web Part page identifies a Web Part with the version number that is specified in the web.config file. With the AssemblyVersion property set to auto-increment, when you recompile and redeploy the Web Part after importing it into a Web Part Page, the SharePoint Web Part framework looks for the version number that is specified in the web.config file. If the version number does not match the deployed Web Part, an error occurs. To prevent the Web Part version number from incrementing each time you recompile, set the version number of the Upcoming Tasks Web Part assembly.
On the Visual Studio Project menu, click ProjectServerWebParts Properties.
On the project properties page, on the Application tab, click Assembly Information.
In the Assembly Information dialog box, specify 1.0.0.0 for the Assembly Version.
Click OK to save the changes.
Close the project properties page.
You must sign the Upcoming Tasks Web Part assembly with a strong name before you can deploy it to the global assembly cache on the Project Server computer. A strong name consists of the assembly's identity—its simple text name, version number, and culture information (if provided)—plus a public key and a digital signature.
On the Visual Studio Project menu, click ProjectServerWebParts Properties.
On the project properties page, on the Signing tab, select the Sign the assembly check box.
In the Choose a strong name key file list, click <New...>.
In the Create Strong Name Key dialog box, type keyfile as the key file name, and then clear the Protect my key file with a password check box.
Close the project properties page.
After adding the required references, setting the assembly's version number, and signing the assembly, the next step is to add the code that implements the Upcoming Tasks Web Part. Add the following Imports or using statements to the top of the source file for the Web Part. For the Visual C# case, add the using statements after the using statements that were generated by Visual Studio when it created the project.
Imports System.Drawing
Imports System.Xml.Serialization
Imports System.Net
Imports System.Data
Imports Microsoft.SharePoint.WebPartPages
using System.Drawing;
using System.Xml.Serialization;
using System.Net;
using System.Data;
using Microsoft.SharePoint.WebPartPages;
The Imports and using statements make it possible to use the classes and types defined in the referenced namespaces without having to use fully qualified namespace paths.
Replace the version of the UpcomingTasksWebPart class definition generated by Visual Studio with the following code.
<XmlRoot(Namespace:="ProjectServerWebParts")> _
Public Class UpcomingTasksWebPart
Inherits WebPart
' URI of the Project Web Access server. Change to an
' appropriate value.
Private PROJECT_SERVER_URI As String = _
"http://ServerName/pwa"
Private PROJECT_WEBSERVICE As String = _
"/_vti_bin/psi/project.asmx"
' Project name in which to look up tasks.
Private m_projectName As String = String.Empty
' Number of upcoming tasks to display.
Private m_numTasks As Integer = 0
' The data grid to display on the Web Part.
Private displayGrid As DataGrid = Nothing
' Project Web Service.
Private projWS As ProjectWS.Project = Nothing
#Region "Properties"
' Handles the connection to the Project Web Service.
' This is a public property so that the tool part can use
' the same connection.
ReadOnly Property ProjectWS() As ProjectWS.Project
Get
' If you are not connected to a project server, make the
' connection.
If projWS Is Nothing Then
projWS = New ProjectWS.Project()
projWS.Url = PROJECT_SERVER_URI + PROJECT_WEBSERVICE
projWS.CookieContainer = New CookieContainer()
projWS.Credentials = _
CredentialCache.DefaultCredentials
End If
Return projWS
End Get
End Property
' These properties are exposed so the tool part can update
' the project name and number of tasks to display.
<Browsable(False), _
Category("Miscellaneous"), _
WebPartStorage(Storage.Personal)> _
Property ProjectName() As String
Get
Return m_projectName
End Get
Set(ByVal value As String)
m_projectName = value
End Set
End Property
<Browsable(False), _
Category("Miscellaneous"), _
WebPartStorage(Storage.Personal)> _
Property NumDisplayTasks() As Integer
Get
Return m_numTasks
End Get
Set(ByVal value As Integer)
m_numTasks = value
End Set
End Property
#End Region
' To use your own tool part, you must override the
' GetToolParts method. The custom tool part provides the dynamic
' list of projects to display in the drop-down list.
Public Overrides Function GetToolParts() As ToolPart()
Dim toolParts(2) As ToolPart
toolParts(0) = New CustomPropertyToolPart()
toolParts(1) = New WebPartToolPart()
toolParts(2) = New UTToolPart()
Return toolParts
End Function
' Add an upcoming tasks grid to the Web Part content, and
' add script that gets information from the Project Center Web
' Part.
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
Controls.Add(New LiteralControl("<b>"))
Controls.Add(GetWebPartTitle())
Controls.Add(New LiteralControl("</b><br/><br/>"))
Controls.Add(GetWebPartContent())
MyBase.OnPreRender(e)
End Sub
' Get a title for the Web Part. Show the project name
' or the default instructions if no project is selected.
Private Function GetWebPartTitle() As Control
Dim titleControl As Control
Dim titleControlLabel As Label = New Label()
Dim projName As String = ProjectName
titleControlLabel.ForeColor = System.Drawing.Color.Blue
If Not projName = Nothing And Not projName = String.Empty Then
titleControlLabel.Text = "Upcoming Tasks for Project: " + _
projName
Else
projName = String.Empty
titleControlLabel.Text = _
"Upcoming Tasks: Web Part Configuration Directions"
End If
titleControl = titleControlLabel
Return titleControl
End Function
' Get a project name, find the uncompleted tasks in that project,
' and show the specified number of tasks in a grid.
Private Function GetWebPartContent() As Control
Dim iTask As Integer = 0
Dim projGuid As Guid
Dim projName As String
Dim projectDS As ProjectWS.ProjectDataSet
Dim taskDataRow As DataRow
Dim displayTaskDataRow As DataRow
Dim taskRows As DataRow()
Dim webControl As Control
Dim webControlLabel As Label = New Label()
displayGrid = New DataGrid()
' Get a DataSet of all the projects that the user has
' access to.
Dim projectListDS As ProjectWS.ProjectDataSet = _
ProjectWS.ReadProjectList()
projName = ProjectName
If Not projName = Nothing And Not projName = "" Then
Dim projectRows As DataRow() = _
projectListDS.Project.Select( _
"PROJ_NAME = '" + projName + "'")
If projectRows.Length > 0 Then
projGuid = CType(projectRows(0)("PROJ_UID"), Guid)
' Get a DataSet of all the tasks in a project.
projectDS = ProjectWS.ReadProject(projGuid, _
ProjectServerWebParts.ProjectWS.DataStoreEnum.PublishedStore)
' Create a table with only the three columns you want
' to display in the Web Part.
Dim displayTaskDT As DataTable = New DataTable()
displayTaskDT.Columns.Add(New DataColumn("Task Name", _
projectDS.Task.Columns(projectDS.Task.TASK_NAMEColumn.ColumnName).DataType))
displayTaskDT.Columns.Add(New DataColumn("Start", _
projectDS.Task.Columns(projectDS.Task.TASK_START_DATEColumn.ColumnName).DataType))
displayTaskDT.Columns.Add(New DataColumn("Finish", _
projectDS.Task.Columns(projectDS.Task.TASK_FINISH_DATEColumn.ColumnName).DataType))
' Filter out tasks that are already completed.
taskRows = _
projectDS.Task.Select(projectDS.Task.TASK_PCT_COMPColumn.ColumnName + _
" <> 100 AND " + _
projectDS.Task.TASK_IS_SUMMARYColumn.ColumnName + _
" = 0", _
projectDS.Task.TASK_FINISH_DATEColumn.ColumnName + " ASC")
' Copy the number of tasks defined by the user into
' the data table you created previously.
Do While ((iTask < taskRows.Length) And _
(iTask < NumDisplayTasks))
taskDataRow = taskRows(iTask)
displayTaskDataRow = displayTaskDT.NewRow()
displayTaskDataRow("Task Name") = _
taskDataRow(projectDS.Task.TASK_NAMEColumn.ColumnName)
displayTaskDataRow("Start") = _
taskDataRow(projectDS.Task.TASK_START_DATEColumn.ColumnName)
displayTaskDataRow("Finish") = _
taskDataRow(projectDS.Task.TASK_FINISH_DATEColumn.ColumnName)
displayTaskDT.Rows.Add(displayTaskDataRow)
iTask += 1
Loop
' Bind the data table to the data grid you are using to
' display in the Web Part.
displayGrid.DataSource = displayTaskDT
displayGrid.DataBind()
displayGrid.HeaderStyle.BackColor = _
System.Drawing.Color.Beige
displayGrid.HeaderStyle.HorizontalAlign = _
System.Web.UI.WebControls.HorizontalAlign.Center
displayGrid.BorderStyle = _
System.Web.UI.WebControls.BorderStyle.None
webControl = displayGrid
Else
webControlLabel.Text = _
"<br/>This project has no upcomming tasks " + _
"to display.<br/>"
webControl = webControlLabel
End If
Else ' No project name is selected, so show instructions.
Dim labelText As String = _
"<br/>This Web Part shows the number of tasks " + _
"remaining in a project."
labelText += _
"<br/>Configure this Web Part to select a " + _
"project<br/>"
labelText += _
"and the number of tasks to display. The current " + _
"number is "
labelText += _
NumDisplayTasks.ToString() + ".<br/>"
webControlLabel.Text = labelText
webControl = webControlLabel
End If
Return webControl
End Function
End Class
[XmlRoot(Namespace = "ProjectServerWebParts")]
public class UpcomingTasksWebPart : WebPart
{
// URI of the Project Web Access server. Change to an
// appropriate value.
private const string PROJECT_SERVER_URI =
"http://ServerName/pwa";
private const string PROJECT_WEBSERVICE =
"/_vti_bin/psi/project.asmx";
// Project name in which to look up tasks.
private string projectName;
// Number of upcoming tasks to display.
private int numTasks;
// The data grid to display on the Web Part.
private DataGrid displayGrid;
// Project Web Service.
private ProjectWS.Project projWS = null;
public UpcomingTasksWebPart()
{
}
#region Properties
// Handles the connection to the Project Web Service.
// This is a public property so that the tool part can use
// the same connection.
public ProjectWS.Project ProjectWS
{
get
{
// If you are not connected to a project server, make the
// connection.
if (projWS == null)
{
projWS = new ProjectWS.Project();
projWS.Url = PROJECT_SERVER_URI + PROJECT_WEBSERVICE;
projWS.CookieContainer = new CookieContainer();
projWS.Credentials =
CredentialCache.DefaultCredentials;
}
return projWS;
}
}
// These properties are exposed so the tool part can update
// the project name and number of tasks to display.
[Browsable(false),
Category("Miscellaneous"),
WebPartStorage(Storage.Personal)
]
public string ProjectName
{
get { return projectName; }
set { projectName = value; }
}
[Browsable(false),
Category("Miscellaneous"),
WebPartStorage(Storage.Personal)
]
public int NumDisplayTasks
{
get { return numTasks; }
set { numTasks = value; }
}
#endregion
// To use our own tool part, you must override the
// GetToolParts method. The custom tool part provides the dynamic
// list of projects to display in the drop-down list.
public override ToolPart[] GetToolParts()
{
ToolPart[] toolParts = new ToolPart[3];
toolParts[0] = new CustomPropertyToolPart();
toolParts[1] = new WebPartToolPart();
toolParts[2] = new UTToolPart();
return toolParts;
}
// Add an upcoming tasks grid to the Web Part content, and
// add script that gets information from the Project Center Web
// Part.
protected override void OnPreRender(EventArgs e)
{
Controls.Add(new LiteralControl("<b>"));
Controls.Add(GetWebPartTitle());
Controls.Add(new LiteralControl("</b><br/><br/>"));
Controls.Add(GetWebPartContent());
base.OnPreRender(e);
}
// Get a title for the Web Part. Show the project name
// or the default instructions if no project is selected.
private Control GetWebPartTitle()
{
Control titleControl;
Label titleControlLabel = new Label();
titleControlLabel.ForeColor = System.Drawing.Color.Blue;
string projName = ProjectName;
if (projName != null && projName != string.Empty)
{
titleControlLabel.Text = "Upcoming Tasks for Project: " +
projName;
}
else
{
projName = string.Empty;
titleControlLabel.Text =
"Upcoming Tasks: Web Part Configuration Directions";
}
titleControl = titleControlLabel;
return titleControl;
}
// Get a project name, find the uncompleted tasks in that project,
// and show the specified number of tasks in a grid.
private Control GetWebPartContent()
{
int iTask = 0;
Guid projGuid;
string projName;
ProjectWS.ProjectDataSet projectDS;
DataRow taskDataRow;
DataRow displayTaskDataRow;
DataRow[] taskRows;
Control webControl;
Label webControlLabel = new Label();
displayGrid = new DataGrid();
// Get a DataSet of all the projects that the user has
// access to.
ProjectWS.ProjectDataSet projectListDS =
ProjectWS.ReadProjectList();
projName = ProjectName;
if (projName != null && projName != "")
{
DataRow[] projectRows = projectListDS.Project.Select(
"PROJ_NAME = '" + projName + "'");
if (projectRows.Length > 0)
{
projGuid = (Guid)projectRows[0]["PROJ_UID"];
// Get a DataSet of all the tasks in a project.
projectDS = ProjectWS.ReadProject(projGuid,
ProjectServerWebParts.ProjectWS.DataStoreEnum.PublishedStore);
// Create a table with only the three columns you want
// to display in the Web Part.
DataTable displayTaskDT = new DataTable();
displayTaskDT.Columns.Add(new DataColumn("Task Name",
projectDS.Task.Columns[projectDS.Task.TASK_NAMEColumn.ColumnName].DataType));
displayTaskDT.Columns.Add(new DataColumn("Start",
projectDS.Task.Columns[projectDS.Task.TASK_START_DATEColumn.ColumnName].DataType));
displayTaskDT.Columns.Add(new DataColumn("Finish",
projectDS.Task.Columns[projectDS.Task.TASK_FINISH_DATEColumn.ColumnName].DataType));
// Filter out tasks that are already completed.
taskRows =
projectDS.Task.Select(projectDS.Task.TASK_PCT_COMPColumn.ColumnName +
" <> 100 AND " +
projectDS.Task.TASK_IS_SUMMARYColumn.ColumnName +
" = 0",
projectDS.Task.TASK_FINISH_DATEColumn.ColumnName + " ASC");
// Copy the number of tasks defined by the user into
// the data table you created previously.
while (iTask < taskRows.Length &&
iTask < NumDisplayTasks)
{
taskDataRow = taskRows[iTask];
displayTaskDataRow = displayTaskDT.NewRow();
displayTaskDataRow["Task Name"] =
taskDataRow[projectDS.Task.TASK_NAMEColumn.ColumnName];
displayTaskDataRow["Start"] =
taskDataRow[projectDS.Task.TASK_START_DATEColumn.ColumnName];
displayTaskDataRow["Finish"] =
taskDataRow[projectDS.Task.TASK_FINISH_DATEColumn.ColumnName];
displayTaskDT.Rows.Add(displayTaskDataRow);
iTask++;
}
// Bind the data table to the data grid you are using to
// display in the Web Part.
displayGrid.DataSource = displayTaskDT;
displayGrid.DataBind();
displayGrid.HeaderStyle.BackColor =
System.Drawing.Color.Beige;
displayGrid.HeaderStyle.HorizontalAlign =
HorizontalAlign.Center;
displayGrid.BorderStyle = BorderStyle.None;
webControl = displayGrid;
}
else
{
webControlLabel.Text =
"<br/>This project has no upcomming tasks to " +
"display.<br/>";
webControl = webControlLabel;
}
}
else // No project name is selected, so show instructions.
{
string labelText =
"<br/>This Web Part shows the number of tasks " +
"remaining in a project.";
labelText +=
"<br/>Configure this Web Part to select a " +
"project<br/>";
labelText +=
"and the number of tasks to display. The current " +
"number is ";
labelText +=
NumDisplayTasks.ToString() + ".<br/>";
webControlLabel.Text = labelText;
webControl = webControlLabel;
}
return webControl;
}
}
The next step is to create the ToolPart class used by the Upcoming Tasks Web Part.
In Visual Studio Solution Explorer, right-click the ProjectServerWebParts project. On the Add menu, click Class.
In the Add New Item dialog box, specify the name of the code file as UTToolPart.cs or UTToolPart.vb, depending on which language you are using, and then click Add. Visual Studio adds the class to the project.
Figure 2. Adding the ToolPart class
Replace the contents of the UTToolPart.cs or UTToolPart.vb file generated by Visual Studio with the following code.
Imports System.Web.UI Imports Microsoft.SharePoint.WebPartPages ' This tool part provides the user a way to select which project's ' tasks to display and the number of upcoming tasks to display. Public Class UTToolPart Inherits ToolPart ' Name of project. Private fieldProjectName As String = String.Empty ' Number of tasks to display. Private fieldNumDisplayTasks As String = String.Empty ' Provides unique names for the controls. Private Sub UTToolPart_Init(ByVal sender As Object, _ ByVal e As System.EventArgs) fieldProjectName = Me.UniqueID + "ProjectName" fieldNumDisplayTasks = Me.UniqueID + "NumDisplayTasks" End Sub Sub New() Me.Title = "Display Details" AddHandler Me.Init, AddressOf UTToolPart_Init End Sub ' Save the project name and number of tasks to display ' in the UpcomingTasksWP class properties Public Overrides Sub ApplyChanges() Dim upcomingTasksWebPart As UpcomingTasksWebPart = _ CType(Me.ParentToolPane.SelectedWebPart, _ UpcomingTasksWebPart) upcomingTasksWebPart.ProjectName = _ Page.Request.Form(fieldProjectName) upcomingTasksWebPart.NumDisplayTasks = _ Convert.ToInt32(Page.Request.Form(fieldNumDisplayTasks)) MyBase.ApplyChanges() End Sub ' Create the drop-down list for the project names and ' the text box for the number of tasks to display. Protected Overrides Sub RenderToolPart( _ ByVal textOutput As HtmlTextWriter) Dim upcomingTasksWebPart As UpcomingTasksWebPart = _ CType(Me.ParentToolPane.SelectedWebPart, _ UpcomingTasksWebPart) ' Read all the project names the user has access to. Dim projectDS As ProjectWS.ProjectDataSet = _ upcomingTasksWebPart.ProjectWS.ReadProjectList() textOutput.Write("<br/>") textOutput.Write("Project: ") textOutput.Write("<br/>") textOutput.Write("<select NAME = '" + fieldProjectName + "'>") For Each projectRow As DataRow In projectDS.Project If projectRow("PROJ_NAME").ToString() = _ upcomingTasksWebPart.ProjectName Then textOutput.Write("<option selected VALUE='" + _ projectRow("PROJ_NAME") + "'>" + _ projectRow("PROJ_NAME")) Else textOutput.Write("<option VALUE='" + _ projectRow("PROJ_NAME") + "'>" + _ projectRow("PROJ_NAME")) End If Next textOutput.Write("</select>") textOutput.Write("<br/>") textOutput.Write("<br/>") textOutput.Write("Number of Tasks to Display:") textOutput.Write("<br/>") textOutput.Write("<input type='text' name='" + _ fieldNumDisplayTasks + "' value='" + _ upcomingTasksWebPart.NumDisplayTasks.ToString() + "'>") End Sub End Class
using System; using System.Web.UI; using System.Data; using Microsoft.SharePoint.WebPartPages; namespace ProjectServerWebParts { // This tool part provides the user a way to select which project's // tasks to display and the number of upcoming tasks to display. public class UTToolPart : ToolPart { private string fieldProjectName; // Name of project. private string fieldNumDisplayTasks; // Number of tasks to // display. // Provides unique names for the controls. private void UTToolPart_Init(object sender, System.EventArgs e) { fieldProjectName = this.UniqueID + "ProjectName"; fieldNumDisplayTasks = this.UniqueID + "NumDisplayTasks"; } public UTToolPart() { this.Title = "Display Details"; this.Init += new EventHandler(UTToolPart_Init); } // Save the project name and number of tasks to display // in the UpcomingTasksWebPart class properties. public override void ApplyChanges() { UpcomingTasksWebPart upcomingTasksWebPart = (UpcomingTasksWebPart)this.ParentToolPane.SelectedWebPart; upcomingTasksWebPart.ProjectName = Page.Request.Form[fieldProjectName]; upcomingTasksWebPart.NumDisplayTasks = Convert.ToInt32(Page.Request.Form[fieldNumDisplayTasks]); base.ApplyChanges(); } // Create the drop-down list for the project names and // the text box for the number of tasks to display. protected override void RenderToolPart( HtmlTextWriter textOutput) { UpcomingTasksWebPart upcomingTasksWebPart = (UpcomingTasksWebPart)this.ParentToolPane.SelectedWebPart; // Read all the project names the user has access to. ProjectWS.ProjectDataSet projectDS = upcomingTasksWebPart.ProjectWS.ReadProjectList(); textOutput.Write("<br/>"); textOutput.Write("Project: "); textOutput.Write("<br/>"); textOutput.Write("<select NAME = '" + fieldProjectName + "'>"); foreach (DataRow projectRow in projectDS.Project) { if (projectRow["PROJ_NAME"].ToString() == upcomingTasksWebPart.ProjectName) { textOutput.Write("<option selected VALUE='" + projectRow["PROJ_NAME"] + "'>" + projectRow["PROJ_NAME"]); } else { textOutput.Write("<option VALUE='" + projectRow["PROJ_NAME"] + "'>" + projectRow["PROJ_NAME"]); } } textOutput.Write("</select>"); textOutput.Write("<br/>"); textOutput.Write("<br/>"); textOutput.Write("Number of Tasks to Display:"); textOutput.Write("<br/>"); textOutput.Write("<input type='text' name='" + fieldNumDisplayTasks + "' value='" + upcomingTasksWebPart.NumDisplayTasks + "'>"); } } }
To deploy the Upcoming Tasks Web Part to a Project Web Access server, use the following procedure.
Copy the Upcoming Tasks Web Part assembly to the target computer by doing the following:
Copy the compiled assembly (ProjectServerWebParts.dll) to any convenient folder on the target computer.
Open the global assembly cache on the Project Web Access server. On the Start menu, click Run, and then type assembly.
Drag the ProjectServerWebParts.dll file from the temporary folder to the global assembly cache window.
Right-click the assembly file in the global assembly cache window, click Properties, double-click the value of the Public Key Token, and then copy it to the Clipboard.
Register the Upcoming Tasks Web Part as a safe control. Open the web.config file for the Project Web Access site where you want to add the Web Part. There are typically several Web sites on a server, and there can also be several Project Web Access sites. To find the correct Web.config file, do the following:
In Internet Information Services (IIS) Manager, expand the Web Sites node, right-click the Project Web Access site you want, and then click Properties. In many cases, Project Web Access is in the Default Web Site.
In the Web Site Properties dialog box, click the Home Directory tab. The web.config file in the directory specified in the Local path box is the file to modify.
Add the following <SafeControl/> tag to the <SafeControls></SafeControls> section of the web.config file.
<SafeControl Assembly="ProjectServerWebParts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[PKToken]" Namespace=" ProjectServerWebParts" TypeName="*" Safe="True" />
Replace the [PKToken] placeholder shown earlier for the PublicKeyToken value with the public key token copied in Step 1.
Restart IIS. In a Command Prompt window on the server, type iisreset.
Create a Web Part definition file for the Upcoming Tasks Web Part:
Open a new file in a text editor such as Notepad, and add the following XML code to the file.
<?xml version="1.0"?> <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2"> <Assembly>ProjectServerWebParts, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=[PKToken]</Assembly> <TypeName>ProjectServerWebParts.UpcomingTasksWebPart</TypeName> <Title>Upcoming Tasks Web Part</Title> <Description>Shows upcoming tasks for a project.</Description> </WebPart>
Replace the [PKToken] placeholder shown earlier for the PublicKeyToken value with the public key token copied previously in Step 1.
Save the file as UpcomingTasksWebPart.dwp to a folder where it is accessible from Office SharePoint Server.
Add the Upcoming Tasks Web Part to the Web Part gallery:
Open Project Web Access, and on the Site Actions menu, click Site Settings.
On the Site Settings page, in the Galleries section, click Web Parts.
On the Web Part Gallery page, click Upload.
On the Upload Web Part: Web Part Gallery page, browse to the UpcomingTasksWebPart.dwp file you created previously. Select Overwrite existing file(s), and then click OK.
The UpcomingTasksWebPart.dwp file provisions the Web Part Gallery: UpcomingTasksWebPart page.
Figure 3. Adding Web Part to Web Part gallery
In the Group section, select Default Web Parts in the drop-down list.
To include the Upcoming Tasks Web Part in the Quick Add Groups list, click Default. To leave the custom Web Part out of the list, clear both check boxes, and then click OK.
After you deploy the Upcoming Tasks Web Part to the Project Web Access server, test it by doing the following:
Open Project Web Access in the browser and navigate to the Project Web Access home page.
Click the Site Actions menu, and then click Edit Page.
Click Add a Web Part in the Footer Web Part zone.
In the Add Web Parts to footer dialog box, locate the Default Web Parts category and select the Upcoming Tasks Web Part.
Figure 4. Adding Web Part
Click Add to add the Web Part to the zone. The Upcoming Tasks Web Part is displayed, showing the default configuration directions.
Figure 5. Default configuration directions
In the Web Part menu, click Modify Shared Web Part to display the tool pane.
In the Appearance, Layout, and Advanced sections of the Upcoming Tasks tool pane, make any changes you want.
Expand the Display Details section of the tool pane, and then select the project and number of tasks to display.
Click Apply to apply the changes. The Upcoming Tasks Web Part displays the open tasks for the selected project.
Figure 6. Displaying open tasks
Note
You might need to stop and then start IIS on the Project Web Access computer before you can add the Upcoming Tasks Web Part to a zone.
This article explores creating a custom Web Part for Project Server 2007. The key steps are:
Creating a Web Control Library project in Visual Studio 2005.
Adding the required references.
Setting the Web Part assembly version number.
Signing the Web Part assembly with a strong name.
Adding the code that implements the functionality of the Web Part that displays the upcoming tasks for a specified project.
Deploying the Web Part.