In MOSS we can filter some data on the currently logged User using the ‘Current User Filter Web Part’, unfortunately it’s not available in WSS. However building a simple Web Part that retriever the current user and that can be employed as a connection provider for other Web Parts isn’t that difficult.

To create a Web Part that act a data provider using the standard WSS/SharePoint infrastructure all you have to do is to implement the ITransformableFilterValues interface. You can then specify if your Web Part will provide single or multiple values for the parameter it will expose, if it can support an empty value and so on.

Accessing the currently logged user is extremely simple, actually it’s just a single line of code:

SPUser user = SPContext.Current.Web.CurrentUser;

We cannot return a plain SPUser object as the values of our provider Web Part, because the ITransformableFilterValues.ParameterValues that is actually used to return values to the callers is of type ReadOnlyCollection<string>.

So we have to find a way to return a single property and convert it to a string that is usable by the consumer; for this first barbaric implementation we simply define an enumeration that will state which field to extract and send to the consumer.

public enum ReturnType
{
   Name,
   ID
}

As an added feature we want to be able to filter on the currently logged and on the groups he belongs to (a thing that isn’t easily done using the standard WebParts that WSS offers); so our Web Part will return multiple values for it’s ‘CurrentUser’ parameter, the first value will always be the username or the user id, followed by the names or ids of the groups to which he belongs to.

Returning the user data as first parameter guarantees that you can use this filter provider with the standard ListViewWebPart (or other Web Parts) that WSS provides.

Here’s the actual implementation code:

[Guid("bf1f0d2a-eb32-4cbf-a3a0-561ae42bdf96")]
public class CurrentUserAndGroupsFilterWebPart : wsswebparts.WebPart, wsswebparts.ITransformableFilterValues
{
   public CurrentUserAndGroupsFilterWebPart()
   {
      ReturnType = ReturnType.Name;
   }
 
   /// <summary>
   /// The Default View of the list
   /// </summary>
   [Personalizable(true),
    WebBrowsable(),
    WebPartStorage(Storage.Shared),
    SPWebCategoryName("Settings"),
    WebDisplayName("Return Type"),
    WebDescription("Select if use the Name or the ID as the values retuned to the consumers")]
   public ReturnType ReturnType { get; set; }
 
   // 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 "CurrentUser";
      }
   }
 
   [wsswebparts.WebPartStorage(wsswebparts.Storage.None)]
   public virtual ReadOnlyCollection<string> ParameterValues
   {
      get
      {
         List<string> data = new List<string>();
 
         // you have to filter on the same value that is displayed.
         SPUser user = SPContext.Current.Web.CurrentUser;
         // string strUser = "<Value Type='User'>" + user.ID + ";#" + user.LoginName + "</value>";
         if (user.IsSiteAdmin)
         {
            return null;
         }
 
         data.Add(ExtractData(user, this.ReturnType));
         foreach (SPGroup g in user.Groups)
         {
            data.Add(ExtractData(g, this.ReturnType));
         }
 
         return new ReadOnlyCollection<string>(data);
      }
   }
 
   private string ExtractData(SPPrincipal principal, ReturnType rt)
   {
      switch (rt)
      {
         case ReturnType.ID:
            return principal.ID.ToString();
         default:
            return principal.Name;
      }
   }
 
   // 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("Current User And Groups", "CurrentUserAnGroupsID", AllowsMultipleConnections = true)]
   public wsswebparts.ITransformableFilterValues SetConnectionInterface()
   {
      return this;
   }
}

To use this Web Part just instantiate it on a page with a ListViewWebPart (the standard control that renders a document library is a ListViewWebPart), define a view on the list that will expose some data related to a user (it can be the standard Author field or a custom ‘User or Group’ field), wire up the two and you have your list filtered on the currently logged user.

Beware that the data returned by the filter Web Part and the data exposed by the view must match...so if you expose the ID, select the ID as the returned type of the filter.

In a next post I will show how you can modify the CustomListViewWebPart I presented earlier (Create a Custom ListViewWebPart) and allow it to become a multiple filters consumer (supporting multiple values for filters too), a thing that I wasn’t able to obtain using the standard Web Parts in WSS or MOSS.

Related Content