Writing a Filter Provider Web Part for Windows SharePoint Services 3.0

Applies to:  Windows SharePoint Services 3.0

Joel Krist, iSoftStone

May 2007

As in previous releases, Windows SharePoint Services 3.0 uses the ASP.NET Web Part connection framework to connect Web Parts to each other programmatically. Filter Web Parts use this connectivity support to provide filter criteria to other Web Parts. Developers can now allow users to provide search or filter criteria. Web Part connections are based on the concepts of "providers" and "consumers." A provider Web Part supplies information to one or more consumer Web Parts through a programmatic interface.

This Office Visual How To illustrates the steps to create a filter provider Web Part for Windows SharePoint Services by presenting code that implements a geographic region filter. The Geographic Region filter provider Web Part displays a user interface that allows users to select one or more geographic regions.

For information on creating the News Headlines filter consumer Web Part that works with the Geographic Region filter provider Web Part, see the Office Visual How To titled "Writing a Filter Consumer Web Part for Windows SharePoint Services 3.0 Using Excel Services."

Watch the Video

Length: 08:12 | Size: 9.90 MB | Type: WMV

Code It | Read It | Explore It

Code It

Download the Code Sample

This section walks through the five major steps to create the Geographic Region filter provider Web Part:

  1. Create a Web Control Library project in Microsoft Visual Studio 2005.

  2. Add a reference to the Windows SharePoint Services assembly.

  3. Set the Web Part assembly version number.

  4. Sign the Web Part assembly with a strong name.

  5. Add the code that implements the functionality of the Geographic Region filter provider Web Part.

Create a Web Control Library Project in Visual Studio 2005

An easy way to create a filter provider Web Part assembly is to use the Visual Studio 2005 Web Control Library template. To create a Web Control Library project in Visual Studio 2005 do the following:

To create a Web Control Library project in Visual Studio 2005

  1. Start Visual Studio.

  2. On the File menu, point to New, and then click Project. The New Project dialog box appears.

  3. In the Project Types pane, select Visual C# or Visual Basic and then select the Windows category.

  4. In the Templates pane, select Web Control Library.

  5. Specify RegionFilterWebPart for the name of the project.

  6. Specify a location for the project and click OK. Visual Studio generates a Web Control Library project containing a single source file named WebCustomControl1.cs or WebCustomControl1.vb, depending on the language selected in step 3.

  7. Rename the WebCustomControl1.cs or WebCustomControl1.vb source file to RegionFilterWebPart.cs or RegionFilterWebPart.vb, depending on the language being used, by right-clicking the file name in Solution Explorer and clicking Rename.

Add a Reference to the Windows SharePoint Services Assembly

The class that implements the Geographic Region filter provider Web Part is derived from the Microsoft.SharePoint.WebPartPages.WebPart class. A reference to the Windows SharePoint Services assembly must be added to the project to allow this class to be used. If Visual Studio is running on a computer that has Office SharePoint Server 2007 installed, follow this procedure.

To add a reference to the Windows SharePoint Services assemblies

  1. On the Project menu, click Add Reference. The Add Reference dialog box appears.

  2. Click the .NET tab. Locate and select the Windows SharePoint Services component (Microsoft.SharePoint.dll).

  3. Click OK to add the references.

If Visual Studio is running on a computer that does not have Office SharePoint Server 2007 installed, the Windows SharePoint Services assembly are not available. In this case, copy the SharePoint assembly from a computer that has Office SharePoint Server 2007 installed to a local project folder on the development computer. The assembly file needed to create the Geographic Region filter provider Web Part is Microsoft.SharePoint.dll. By default, this assembly is located in the following folder on a computer that has Office SharePoint Server 2007 installed:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI

After you create a local copy of the SharePoint assembly, you can add a reference to Microsoft.SharePoint.dll by browsing for the local file.

To add a reference to the local copy of the assembly

  1. On the Project menu, click Add Reference. The Add Reference dialog box appears.

  2. Click the Browse tab and navigate to the local folder containing the copy of the Windows SharePoint Services assembly.

  3. Select the Microsoft.SharePoint.dll file.

  4. Click OK to add the reference.

Set the Version Number of the Web Part Assembly

By default, the AssemblyVersion property of the Web Control Library 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 autoincrement, if the Web Part is recompiled and redeployed after importing it into a Web Part page, the Web Part framework compares the version number that is specified in the web.config file and the version number of the deployed Web Part. If the version numbers do not match, an error occurs. To prevent the version number of the Web Part from being incremented each time a recompilation is done, set the version number of the Web Part assembly.

To set the version number of the Web Part assembly

  1. Click the Project menu, and then click RegionFilterWebPart Properties.

  2. On the project Properties page, click the Application tab.

  3. Click Assembly Information.

  4. In the Assembly Information dialog box, specify 1.0.0.0 for the assembly version.

  5. Click OK to save the changes.

  6. Close the project Properties page.

Sign the Web Part Assembly with a Strong Name

To allow the Web Part assembly to be installed in the global assembly cache so that it can be shared among multiple applications, it must be signed with a strong name. 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.

To assign a strong name to the Web Part assembly in Visual Studio

  1. Click the Project menu and then click RegionFilterWebPart Properties.

  2. On the project Properties page, click the Signing tab.

  3. Select the Sign the assembly check box.

  4. In the Choose a strong name key file list, select <New...>.

  5. In the Create Strong Name Key dialog box, enter keypair as the key file name, and clear the Protect my key file with a password check box.

  6. Close the project Properties page.

Implement the Geographic Region Filter Provider Web Part

The next step is to create the class that provides the implementation of the Geographic Region filter provider Web Part. Add the following Imports or using statements to the top of the source file for the Web Part, replacing the Imports or using statements that were generated by Visual Studio when the project was created.

Imports wsswebparts = Microsoft.SharePoint.WebPartPages
Imports aspnetwebparts = System.Web.UI.WebControls.WebParts
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls
Imports System.Collections.ObjectModel
using wsswebparts = Microsoft.SharePoint.WebPartPages;
using aspnetwebparts = System.Web.UI.WebControls.WebParts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Collections.ObjectModel;

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.

Next, add code to the RegionFilterWebPart class so that it does the following:

  1. Creates a user interface with check box controls for selecting regions.

  2. Implements the ITransformableFilterValues interface so that the Geographic Region filter provider Web Part can connect to filter consumer Web Parts.

  3. Exposes a provider connection point to return an ITransformableFilterValues interface instance with the currently selected region values.

Replace the entire existing RegionFilterWebPart class definition with the following code.

Public Class RegionFilterWebPart
    Inherits wsswebparts.WebPart
    Implements wsswebparts.ITransformableFilterValues

    Dim cblRegionList As CheckBoxList
    Dim cbitemRegion As ListItem

    ' Implementations of the ITransformableFilterValues properties.
    <wsswebparts.WebPartStorage(wsswebparts.Storage.None)> _
    Public Overridable ReadOnly Property AllowMultipleValues() _
    As Boolean _
    Implements _
    wsswebparts.ITransformableFilterValues.AllowMultipleValues
        Get
            Return True
        End Get
    End Property

    <wsswebparts.WebPartStorage(wsswebparts.Storage.None)> _
    Public Overridable ReadOnly Property AllowAllValue() As Boolean _
    Implements wsswebparts.ITransformableFilterValues.AllowAllValue
        Get
            Return True
        End Get
    End Property

    <wsswebparts.WebPartStorage(wsswebparts.Storage.None)> _
    Public Overridable ReadOnly Property AllowEmptyValue() As Boolean _
    Implements wsswebparts.ITransformableFilterValues.AllowEmptyValue
        Get
            Return False
        End Get
    End Property

    <wsswebparts.WebPartStorage(wsswebparts.Storage.None)> _
    Public Overridable ReadOnly Property ParameterName() As String _
    Implements wsswebparts.ITransformableFilterValues.ParameterName
        Get
            Return "Geographic Region"
        End Get
    End Property

    <wsswebparts.WebPartStorage(wsswebparts.Storage.None)> _
    Public Overridable ReadOnly Property ParameterValues() _
    As ReadOnlyCollection(Of String) _
    Implements wsswebparts.ITransformableFilterValues.ParameterValues
        Get
            Dim values() As String = GetCurrentlySelectedGeographies()
            If values Is Nothing Then
                Return Nothing
            Else
                Return New ReadOnlyCollection(Of String)(values)
            End If
        End Get
    End Property

    Protected Overrides Sub CreateChildControls()
        cblRegionList = New CheckBoxList()
        cblRegionList.AutoPostBack = True
        Controls.Add(cblRegionList)

        cbitemRegion = New ListItem()
        cbitemRegion.Text = "Redmond"
        cblRegionList.Items.Add(cbitemRegion)
        cbitemRegion = Nothing

        cbitemRegion = New ListItem()
        cbitemRegion.Text = "Seattle"
        cblRegionList.Items.Add(cbitemRegion)
        cbitemRegion = Nothing

        cbitemRegion = New ListItem()
        cbitemRegion.Text = "US"
        cblRegionList.Items.Add(cbitemRegion)
        cbitemRegion = Nothing

        cbitemRegion = New ListItem()
        cbitemRegion.Text = "World"
        cblRegionList.Items.Add(cbitemRegion)
        cbitemRegion = Nothing

        cbitemRegion = New ListItem()
        cbitemRegion.Text = "All"
        cblRegionList.Items.Add(cbitemRegion)
        cbitemRegion = Nothing

        MyBase.CreateChildControls()
    End Sub

    ' Use the ConnectionProvider attribute to specify the method that
    ' the Web Part framework should call to allow us to return an instance
    ' of our ITransformableFilterValues interface.
    <aspnetwebparts.ConnectionProvider("Region Filter", _
    "ITransformableFilterValues", AllowsMultipleConnections:=True)> _
    Public Function SetConnectionInterface() _
    As wsswebparts.ITransformableFilterValues
        Return Me
    End Function

    Public Function GetCurrentlySelectedGeographies() As String()
        Dim choices(5) As String
        Dim anythingSelected As Boolean = False

        ' It's possible for the ParameterValues property to be accessed
        ' before CreateChildControls has been called, so ensure the
        ' Region List combobox has been created.
        If cblRegionList Is Nothing Then
            choices = Nothing
            Return choices
        End If

        For i As Integer = 0 To cblRegionList.Items.Count - 1
            ' Get the selected choices
            If cblRegionList.Items(i).Selected Then
                anythingSelected = True

                If cblRegionList.Items(i).Text <> "All" Then
                    choices(i) = cblRegionList.Items(i).Text
                Else
                    choices = Nothing
                    Return choices
                End If
            End If
        Next i

        If Not anythingSelected Then
            choices = Nothing
        End If

        Return choices
    End Function

    Protected Overrides Sub RenderContents _
    (ByVal output As HtmlTextWriter)
        EnsureChildControls()
        RenderChildren(output)
    End Sub

End Class
public class RegionFilterWebPart:
    wsswebparts.WebPart, wsswebparts.ITransformableFilterValues
{
    CheckBoxList cblRegionList;
    ListItem cbitemRegion;

    protected override void CreateChildControls()
    {
        cblRegionList = new CheckBoxList();
        cblRegionList.AutoPostBack = true;
        Controls.Add(cblRegionList);

        cbitemRegion = new ListItem();
        cbitemRegion.Text = "Redmond";
        cblRegionList.Items.Add(cbitemRegion);
        cbitemRegion = null;

        cbitemRegion = new ListItem();
        cbitemRegion.Text = "Seattle";
        cblRegionList.Items.Add(cbitemRegion);
        cbitemRegion = null;
        
        cbitemRegion = new ListItem();
        cbitemRegion.Text = "US";
        cblRegionList.Items.Add(cbitemRegion);
        cbitemRegion = null;

        cbitemRegion = new ListItem();
        cbitemRegion.Text = "World";
        cblRegionList.Items.Add(cbitemRegion);
        cbitemRegion = null;

        cbitemRegion = new ListItem();
        cbitemRegion.Text = "All";
        cblRegionList.Items.Add(cbitemRegion);
        cbitemRegion = null;

        base.CreateChildControls();
    }

    // Implementations of the ITransformableFilterValues properties.
    [wsswebparts.WebPartStorage(wsswebparts.Storage.None)]
    public virtual bool AllowMultipleValues
    {
        get
        {
            return true;
        }
    }

    [wsswebparts.WebPartStorage(wsswebparts.Storage.None)]
    public virtual bool AllowAllValue
    {
        get
        {
            return true;
        }
    }

    [wsswebparts.WebPartStorage(wsswebparts.Storage.None)]
    public virtual bool AllowEmptyValue
    {
        get
        {
            return false;
        }
    }
    
    [wsswebparts.WebPartStorage(wsswebparts.Storage.None)]
    public virtual string ParameterName
    {
        get
        {
            return "Geographic Region";
        }
    }

    [wsswebparts.WebPartStorage(wsswebparts.Storage.None)]
    public virtual ReadOnlyCollection<string> ParameterValues
    {
        get
        {
            string[] values = this.GetCurrentlySelectedGeographies();
            return values == null ?
                null :
                new ReadOnlyCollection<string>(values);
        }
    }
   
    public string[] GetCurrentlySelectedGeographies()
    {
        String[] choices = new String[5];
        bool anythingSelected = false;

        // It's possible for the ParameterValues property to be accessed
        // before CreateChildControls has been called, so ensure the
        // Region List combobox has been created.
        if (cblRegionList == null)
        {
            choices = null;
            return choices;
        }

        for (int i = 0; i < cblRegionList.Items.Count; i++)
        {
            // Get the selected choices
            if (cblRegionList.Items[i].Selected)
            {
                anythingSelected = true;
                if (cblRegionList.Items[i].Text != "All")
                {
                    choices[i] = cblRegionList.Items[i].Text;
                }
                else
                {
                    choices = null;
                    return choices;
                }
            }

        }
        
        if (!anythingSelected)
            choices = null;

        return choices;
    }

    // Use the ConnectionProvider attribute to specify the method that
    // the Web Part framework should call to allow us to return an instance
    // of our ITransformableFilterValues interface.
    [aspnetwebparts.ConnectionProvider("Region Filter",
     "ITransformableFilterValues", AllowsMultipleConnections = true)]
    public wsswebparts.ITransformableFilterValues 
    SetConnectionInterface()
    {
        return this;
    }

    protected override void RenderContents(HtmlTextWriter output)
    {
        this.EnsureChildControls();
        RenderChildren(output);
    }
}

Read It

Introduced in Windows SharePoint Services 3.0, filter Web Parts use the Web Part connection support to provide filter criteria from one Web Part (the "provider" Web Part) to another Web Part (the "consumer" Web Part). This makes it possible for developers to build more sophisticated applications incorporating the 2007 Microsoft Office system by enabling users to provide search and filter criteria.

To learn how to package and deploy the Geographic Region filter provider Web Part created in this Visual How To, and how to improve the appearance and configurability of a Web Part, see Deploying and Optimizing a SharePoint Web Part That Calls Excel Web Services.

Explore It