Read-only Workset API

Another one of the new Revit 2012 API features that we still never had a detailed look at is the worksharing API, a comprehensive read-only API to worksharing features, access the list of worksets, find out what elements are in a workset, who borrowed what, whether an element went out of date with central, etc. Here is a quick Q & A on some basic aspects of that API:

Question: I know that the built-in parameter ELEM_PARTITION_PARAM identifies the workset of an element in some manner. Its value is an integer. How can I retrieve the workset name from this value?

Answer: The integer value stored in the parameter is actually the workset id, which is used as a key in the workset table.

To access the workset, you therefore first have to obtain the document workset table, for instance via the GetWorksetTable method:

  WorksetTable worksetTable
    = doc.GetWorksetTable();

You can then create a workset id from the parameter value and access the workset of a given element 'e' using that:

  Parameter p = e.get_Parameter(
    BuiltInParameter.ELEM_PARTITION_PARAM );
 
  int paramValue = param.AsInteger();
 
  WorksetId wid = new WorksetId( paramValue );
 
  Workset workset = WorksetId.InvalidWorksetId == wid
    ? null
    : worksetTable.GetWorkset( wid );

Just like a standard Revit database element, the workset provides a property returning its name.

There is also a simpler direct way to access the workset of an element, however, using the document method GetWorksetId, which returns the workset id for a given element id:

  WorksetId wid = doc.GetWorksetId( e.Id );

Question: How can I iterate the workset table to obtain a list of all the worksets defined in the project?

Answer: There are dedicated FilteredWorksetCollector and WorksetFilter classes for that purpose. Here is some sample code demonstrating their use:

  FilteredWorksetCollector coll
    = new FilteredWorksetCollector( doc );
 
  // You may want to filter them...
 
  //coll.OfKind(WorksetKind.UserWorkset);
 
  StringBuilder worksetNames = new StringBuilder();
 
  foreach( Workset workset in coll )
  {
    worksetNames.AppendFormat( "{0}: {1}\n",
      workset.Name, workset.Kind );
  }
 
  TaskDialog.Show( "Worksets",
    worksetNames.ToString() );

As mentioned in the comment, please note that the FilteredWorksetCollector class provides an OfKind method which can be used to limit the filters returned to a given workset kind, e.g. to UserWorkset only, i.e. worksets defined by users, including the two default Revit ones.