You can create an event receiver on your list and then programatically kickstart your workflows in each of the ItemAdded and ItemUpdated events (as apposed to having them start automatically).
This allows you to:
- Determine exactly what event had triggered the workflow, and
- Modify your association data for each scenario, if required (NB: the association data is an XML string containing any custom data that you need to pass to your workflow)
An example...
Let's say you have a basic approval workflow, and the
only difference about the approval process for new vs updated list
items is that the tasks must be sent to a different user / SharePoint group.
Obviously you don't want to create 2x identical workflows here just so
that you can assign them to a different user / SharePoint group! So instead
you create an item event receiver on your list which traps the
ItemAdded and ItemUpdated events. Inside each of these
methods you simply load your one approval workflow and then programmatically assign the appropriate approver to it.
I have provided some code stubs below:
/// <summary>
/// List Item Events
/// </summary>
public class MyListItemEventReceiver : SPItemEventReceiver
{
/// <summary>
/// An item was added.
/// </summary>
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
// Get your approval workflow that is associated with this list.
SPWorkflowAssociation approvalWorkflowAssociation = properties.List.WorkflowAssociations.GetAssociationByName("Approval Workflow", CultureInfo.InvariantCulture);
// Update the association data (this example is purely trivial).
string assigneeElement = @"
<d:Assignee>
<pc:Person>
<pc:DisplayName>Custom Group</pc:DisplayName>
<pc:AccountId>Custom Group</pc:AccountId>
<pc:AccountType>SharePointGroup</pc:AccountType>
</pc:Person>
</d:Assignee>";
string eventData = approvalWorkflowAssociation.AssociationData.Replace("<d:Assignee />", assigneeElement);
// Manually start the workflow, passing it the updated association data.
SPWorkflow approvalWorkflow = properties.Web.Site.WorkflowManager.StartWorkflow(
properties.ListItem,
approvalWorkflowAssociation,
eventData);
}
/// <summary>
/// An item is being updated
/// </summary>
public override void ItemUpdated(SPItemEventProperties properties)
{
// As above :)
}
}