Changes in SharePoint DesignerTypes for workflow activity parameters

Creating a workflow in SharePoint Designer consists of selecting Conditions and Activities to build the logic and determine what actions the workflow performs. When you select an activity or condition a sentence appears in the WorkFlow Designer screen with underlined phrases that allow you click on them to set the workflow’s parameters. These parameters can be selecting a column on a list item and a value to give it, or they can be a user’s account name, a url to a site or something more complex like an email definition that includes a To address, CC address, a subject and a body.

When creating custom workflow activities and conditions for SharePoint in Visual Studio, you create a code class to build its functionality as well as a .actions file, both of which define the parameters. SharePoint Designer uses the .actions to be able to add the activity or condition to a workflow. You must specify the type for each parameter within both the class and the .actions file as well as the DesignerType in the .actions file. When a user clicks on a parameter, different windows open to allow the user to input the values according to the DesignerType given to the parameter. The DesignerType is simply an enumeration that SharePoint Designer uses to determine what type of form to display to gather information on each parameter. For example, a DesignerType of DropDown will present a drop down menu at the location of the parameter phrase in the sentence, whereas a DesignerType of Email will open a pop up window with fields for the To address, CC address, Subject and Body where each of these fields is defined as a parameter of different types in code and returned from the Designer form as an object of that type.

For an activity to send an email, the simple class definition may look something like this:


public partial class SendAnEmail : SequenceActivity
{
   #region Dependency Properties

   public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(SendAnEmail));
   public static DependencyProperty RecipientCCProperty = DependencyProperty.Register("RecipientCC", typeof(ArrayList), typeof(SendAnEmail));
   public static DependencyProperty RecipientFromProperty = DependencyProperty.Register("RecipientFrom", typeof(string), typeof(SendAnEmail));
   public static DependencyProperty RecipientTOProperty = DependencyProperty.Register("RecipientTO", typeof(ArrayList), typeof(SendAnEmail));
   public static DependencyProperty SubjectProperty = DependencyProperty.Register("Subject", typeof (string), typeof (SendAnEmail));
   public static DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof(string), typeof(SendAnEmail));

   #endregion

   public SendAnEmail()
   {
      InitializeComponent();
   }

   #region Activity Parameters

   [Description("Recipient address")]    [Browsable(true)]    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]    public ArrayList RecipientTO
   {
      get { return ((ArrayList) (base.GetValue(RecipientTOProperty))); }
      set { base.SetValue(RecipientTOProperty, value); }
   }

   [Description("Carbon copy recipient")]    [Browsable(true)]    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]    public ArrayList RecipientCC
   {
      get { return ((ArrayList) (base.GetValue(RecipientCCProperty))); }
      set { base.SetValue(RecipientCCProperty, value); }
   }

   [Description("Subject")]    [Browsable(true)]    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]    public string Subject
   {
      get { return ((string) (base.GetValue(SubjectProperty))); }
      set { base.SetValue(SubjectProperty, value); }
   }

   [Description("HTML Body")]    [Browsable(true)]    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]    public string Body
   {
      get { return ((string) (base.GetValue(BodyProperty))); }
      set { base.SetValue(BodyProperty, value); }
   }

   [Browsable(true)]    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]    public WorkflowContext __Context
   {
      get { return ((WorkflowContext) (base.GetValue(__ContextProperty))); }
      set { base.SetValue(__ContextProperty, value); }
   }

   [Description("Sender address. If this value is not specified, default sharepoint sender address will be used")]    [Browsable(true)]    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]    public string RecipientFrom
   {
      get { return ((string) (base.GetValue(RecipientFromProperty))); }
      set { base.SetValue(RecipientFromProperty, value); }
   }

   #endregion

   protected override ActivityExecutionStatus OnExecute(ActivityExecutionContext executionContext, Microsoft.SharePoint.Workflow.ISharePointService service)
   {
   }
}

The .actions file would look like:


<?xml version="1.0" encoding="utf-8"?>
<WorkflowInfo Language="en-us">
   <Actions Sequential="then" Parallel="and">
      <Action Name="Send E-mail Extended" ClassName="SPSolutions.SharePoint.WorkflowEssentials.Activities.SendEmailExtended" Assembly="SPSolutions.SharePoint.WorkflowEssentials, Version=1.0.0.0, Culture=neutral, PublicKeyToken=08a33cc09f006379" AppliesTo="all" Category="SharePoint Solutions' WorkFlow Essentials">
         <RuleDesigner Sentence="Send a %1 e-mail to %2 and display %3 as the sender">
            <FieldBind Field="IsMessageUrgent" DesignerType="Dropdown" Text="choose" Id="1">
               <Option Name="urgent" Value="true"/>
               <Option Name="non urgent" Value="false"/>
            </FieldBind>
            <FieldBind Field="RecipientTO,RecipientCC,Subject,Body" Text="this address" DesignerType="Email" Id="2"/>
            <FieldBind Field="RecipientFrom" Text="this address" Id="3" DesignerType="stringbuilder" />
         </RuleDesigner>
         <Parameters>
            <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In"/>
            <Parameter Name="IsMessageUrgent" Type="System.String, mscorlib" Direction="In" InitialValue="false" />
            <Parameter Name="RecipientTO" Type="System.Collections.ArrayList, mscorlib" Direction="In" />
            <Parameter Name="RecipientCC" Type="System.Collections.ArrayList, mscorlib" Direction="Optional" />
            <Parameter Name="RecipientFrom" Type="System.String, mscorlib" Direction="In" />
            <Parameter Name="Subject" Type="System.String, mscorlib" Direction="In" />
            <Parameter Name="Body" Type="System.String, mscorlib" Direction="In" />
         </Parameters>
      </Action>
   </Actions>
</WorkflowInfo>

In terms of SharePoint 2010, there are several new DesignerTypes and some of the existing ones have changed slightly in the types of parameters that they return. Below is an overview of most, if not all, of the DesignerTypes included in 2010.

 Designer Type 
   
 New to 2010 
   
 Parameter(s) returned
(example parameter name) 
   
 Parameter type 
   
 Description 
 Assignment       Yes       AssignedTo       System.String       
             CC       System.Collections.ArrayList       
             Comments       System.String       
             Subject       System.String       
             Duration       System.Double       
             DurationUnit       Microsoft.Office.Workflow.Actions.DurationUnit       
             DueDate       System.DateTime       
 Boolean       No       Yes/No       System.Boolean       
 ChooseDocLibItem       No       DocumentLibrary
ItemName 
     System.String       Selects list item from a Document Library based on a field value. 
 ChooseListItem       Changed       ListId       System.String       Selects List Item from list based on a field value. 
             ListItem       Microsoft.SharePoint.Workflow.SPItemKey       
 ContentType       Yes       ContentTypeID       System.String       
 CreateListItem       No                   
 DataSourceDropDown       Yes       DataSourceName       System.String       Drop Down list of DataSources for list associated with workflow. 
 Date       No       Date       System.DateTime       Date Time Selector 
 Dependent       Yes            S ystem.String       Based on TextArea DesignerType 
 DropDown       No             System.String       
 Email       No       To       System.Collection.ArrayList       
             CC       System.Collection.ArrayList       
             Subject       System.String       
             Body       System.String       
 Hide       No                   Used to hide parameter from users in Designer 
 FieldNames       No       FieldName       System.String       Select field column from list associated with workflow. 
 Float       No             System.Float       
 HyperLink       No       Link       System.String       
 Integer       No             System.Int32       
 ListItems       Yes             System.String       
 ListNames       No       ListTitle       System.String       Drop Down with list of list names from current site 
 Operator       No                   Drop-down list box control that includes operators used to evaluate each side of the RuleDesigner sentence. Operators are static and must be added in Options elements. 
 ParameterNames       No             System.String       Allows the creation of a new variable for the workflow. 
 Person       No       Users       System.Collections.ArrayList       Allows selection of multiple users 
 SinglePerson       Changed             System.Object       Allows selection of a single user 
 StringBuilder       No             System.String       
 Survey       No                   Creates a task in the workflow to gather data from users. 
 TaskSummary       Yes       TaskProcessName       System.String       
 Text       No             System.Object       
 TextArea       No             System.String       
 UpdateListItem       No       ListItemToUpdate             
 WritableFieldNames       No             System.String       Drop down including list of fields on list that are writable 

So far, the main changes appear in the return types of the ChooseListItem and SinglePerson DesignerTypes. In SharePoint 2010, the SinglePerson form returns a generic System.Object rather than a string, and the ChooseListItem’s ListItem parameter returns a new type of SPItemKey instead of a string.

To accommodate the return of an Object from the SinglePerson DesignerType form, simple define the parameter as System.Object in the .actions file and the DependencyProperty in code, then define the activities property as a String and explicitly convert it from object to string in the get statement.

The new .actions file section would now look like:

<Action Name="myNewActivity"
 ClassName="SPSolutions.SharePoint.WorkflowEssentials.Activities. myNewActivity "
 Assembly="SPSolutions.SharePoint.WorkflowEssentials, Version=1.0.0.0, Culture=neutral,
 PublicKeyToken=08a33cc09f006379"
 AppliesTo="all" Category="SharePoint Solutions' WorkFlow Essentials">
   <RuleDesigner Sentence="Get %1">
     <FieldBind Field="SharePointUser" DesignerType="SinglePerson" Text="this person" Id="1" />
   </RuleDesigner>
   <Parameters>
     <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext,
      Microsoft.SharePoint.WorkflowActions" Direction="In"/>
     <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" />
     <Parameter Name="SharePointUser" Type="System.Object, mscorlib" Direction="In" />
   </Parameters>
 </Action>

The new declaration in the class for parameters returned from the ChooseListItem DesignerType would now look like:

public static DependencyProperty SharePointUserProperty =
DependencyProperty.Register("SharePointUser", typeof(object), typeof(myNewActivity));
[Description("SharePoint User")] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string SharePointUser
{
   get { return ((string) (base.GetValue(SharePointUserProperty))); }
   set { base.SetValue(SharePointUserProperty, value); }
}

The SPItemKey type appears to be a wrapper for returning an instance of the list item. It has two public properties: Id as Int32 and Key as String where the Id is the selected ListItem’s Id and Key is the name. You can programmatically get an instance of the SPListItem by passing the SPList object as a parameter to SPItemKey.GetItemByIdFromList(SPList).

Public Members for Microsoft.SharePoint.Workflow.SPItemKey

Constructors
 SPItemKey()       Returns object with Key = string.Empty, Id = -1 
 SPItemKey(Int32 id)       Returns object with Key = id.ToString(), Id = id 
 SPItemKey(string key)       Returns object with Key = key, Id =Int32.Parse(key) 
Methods
 Equals(object rhs)       Boolean       Determines if current object equals object passed in 
 Equals(object objA, object objB)       Boolean       Determines if two objects are equal 
 Finalize()       Void       Empty override of base System.Object.Finalize() 
 FromItem(SPListItem listItem)       SPItemKey       Returns SPItemKey object given SPListItem 
 GetHashCode()       Int32       Generated from Exclusive OR operation between Id and Key.GetHashCode() 
 GetItemByIdFromList(SPList)       SPItemKey       Returns SPListItem from given list from Key or Id property 
 GetType()       Type       Returns Type for current SPItemKey 
 IsEmpty(SPItemKey)       Boolean       Static. Returns true if both Id and Key properties are null or if Id = -1 and Key is null or string.Empty 
 MemberwiseClone()       Object       Creates a shallow copy of the current SPItemKey 
 op_Equality(SPItemKey lhs, object rhs)       Boolean       Static. Determines if SPItemKey and Object are both null or equal 
 op_Equality(SPItemKey lhs, SPItemKey rhs)       Boolean       Static. Determines if two SPItemKey objects are both null or equal 
 op_Inequality(SPItemKey lhs, object rhs)       Boolean       Static. Determines if SPItemKey and Object are both not null or not equal 
 op_Inequality(SPItemKey lhs, SPItemKey rhs)       Boolean       Static. Determines if two SPItemKey objects are both not null or not equal 
 ReferenceEquals(object objA, object objB)       Boolean       Static. Determines if two objects are references to the same object 
 ToString()       String       Comma separated string: Key, Id 
Properties
 Empty       SPItemKey       Static. Returns empty object using empty constructor 
 Id       Int32       Read/Write. Id of SPItemKey 
 Key       String       Read/Write. Key of SPItemKey 

To access the new type in your class, be sure to reference the new assemblies for SharePoint 14 including C:\Program Files\Common Files\Microsoft Shared\web server extensions\14\ISAPI\Microsoft.SharePoint.dll and C:\Program Files\Common Files\Microsoft Shared\web server extensions\14\ISAPI\Microsoft.SharePoint.WorkflowActions.dll.

The new .actions file section would now look like:

<Action Name="myNewActivity"
 ClassName="SPSolutions.SharePoint.WorkflowEssentials.Activities. myNewActivity"
 Assembly="SPSolutions.SharePoint.WorkflowEssentials, Version=1.0.0.0, Culture=neutral,
 PublicKeyToken=08a33cc09f006379"
 AppliesTo="all" Category="SharePoint Solutions' WorkFlow Essentials">
   <RuleDesigner Sentence="Get %1">
     <FieldBind Field="ListId, ListItem" DesignerType="ChooseListItem" Text="List Item" Id="1" />
   </RuleDesigner>
   <Parameters>
     <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext,
      Microsoft.SharePoint.WorkflowActions" Direction="In"/>
     <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" />
     <Parameter Name="ListItem" Type="Microsoft.SharePoint.Workflow.SPItemKey, Microsoft.SharePoint" Direction="In" />
   </Parameters>
</Action>


The new declaration in the class for parameters returned from the ChooseListItem DesignerType would now look like:

public static DependencyProperty ListIdProperty = DependencyProperty.Register("ListId", typeof(string), typeof(myNewActivity));
[Description("List Id")] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string ListId
{
   get { return ((string) (base.GetValue(ListIdProperty))); }
   set { base.SetValue(ListIdProperty, value); }
}

public static DependencyProperty ListItemProperty = DependencyProperty.Register("ListItem", typeof(SPItemKey), typeof(myNewActivity));
[Description("List Item")] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public SPItemKey ListItem
{
   get { return ((SPItemKey) (base.GetValue(ListItemProperty))); }
   set { base.SetValue(ListItemProperty, value); }
}

Looking at the SharePoint 14 codebase, there are several new activities included in the namespace Microsoft.SharePoint.WorkflowActions.WithKey that use the SPItemKey object includng the same ListItem property as well as additional properties such as TaskId. It appears that the workflow activities in the new version of SharePoint uses this object extensively for List Items, probably as a smaller object to pass around instead of the full SPListItem object. It will be interesting to see how, if at all, this object changes in the beta release.

Related Posts

080912_0319_HowtoAddthe1.png 080912_0319_HowtoAddthe2.png 080912_0319_HowtoAddthe3.png 080912_0319_HowtoAddthe4.png 080912_0319_HowtoAddthe5.png 080912_0319_HowtoAddthe6.png 080912_0319_HowtoAddthe7.png 080912_0319_HowtoAddthe8.png 080912_0319_HowtoAddthe9.png 080912_0319_HowtoAddthe10.png 080912_0319_HowtoAddthe11.png 080912_0319_HowtoAddthe12.png

How to Add the Meeting Workspace Button in the Outlook 2010 Ribbon to Create a Meeting Workspace

SharePointDesignerSQLDataForm.png SharePointDesignerSQLDataForm_thumb.png SharePointDesignerDataViewSQL.png

SharePoint-InfoPath 2007 Video Tutorial: Displaying SQL Data in Data View Web Parts (Part 2)

image.png image_thumb.png image.png image_thumb.png image.png image_thumb.png InfoPathSQLVideoTutorial.png SharePointDesignerSQLDataForm.png SharePointDesignerSQLDataForm_thumb.png SharePointDesignerDataViewSQL.png

SharePoint-InfoPath 2007 Video Tutorial: Storing InfoPath form data in SQL (Part 1)

image.png image_thumb.png SharePointDropDownFilter.png

SharePoint 2010 Tutorial Video: Drop-Down Filters

Leave a Reply