Par Thierry Thoua,
lundi, mars 10 2008.
Lien permanent
WF
La création d'activités dans une dll offre la possibilité de pouvoir la réutiliser dans différents workflows. On sépare proprement le code "business" exécuté avec le workflow. Ce post offre un mini exemple décrivant les différentes étapes pour réaliser une activité que l'on pourra intégrer à nos workflows et ensuite la méthode pour customiser le rendu de l'activité sur le designer de Visual studio (ou dans n'importe quel DSL rendant le workflow ... par exemple ... l'application WorkflowMonitor).
Voici le rendu du workflow basique. Celui-ci se compose de deux activités. L'une génère une path qui sera visible en output et sera utilisé en input dans la seconde activité.
La création d'une activité est simple. Il suffit d'hériter par exemple de Activity et d'overrider la méthode Execute. Pour ce qui est des propriétés qui seront utiliser en "in"/"out", il faut utiliser le même principe que pour windows presentation foundation. On utilise l'objet DependencyProperty. Celui-ci a le même nom que sous WPF mais il ne s'agit pas de la même classe. Les deux classes se trouvent dans un namespace (et assembly) différent. L'utilisation de DependencyProperty offre également la possibilité de spécifier une valeur par défaut pour la propriété etc.
- Activité de génération du path
[Designer(typeof(GenerateNameActivityDesigner))]
[ToolboxBitmap(typeof(GenerateNameActivity), "gnome-fs-directory.png")]
public partial class GenerateNameActivity : System.Workflow.ComponentModel.Activity
{
public static DependencyProperty UserNameGeneratedProperty =
DependencyProperty.Register("UserNameGenerated",
typeof(System.String),
typeof(GenerateNameActivity));
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[DescriptionAttribute("UserNameGenerated")]
[CategoryAttribute("UserNameGenerated Property")]
public string UserNameGenerated
{
get
{
return ((string)(base.GetValue(UserNameGeneratedProperty)));
}
set
{
base.SetValue(UserNameGeneratedProperty, value);
}
}
public GenerateNameActivity()
{
InitializeComponent();
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
UserNameGenerated = Path.GetTempFileName();
return ActivityExecutionStatus.Closed;
}
}
- Activité d'affichage du path généré
public partial class DisplayActivity : System.Workflow.ComponentModel.Activity
{
public static DependencyProperty UserNameProperty =
DependencyProperty.Register("UserName",
typeof(System.String),
typeof(DisplayActivity));
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[DescriptionAttribute("Username")]
[CategoryAttribute("Username Property")]
public string UserName
{
get
{
return ((string)(base.GetValue(UserNameProperty)));
}
set
{
base.SetValue(UserNameProperty, value);
}
}
public DisplayActivity()
{
InitializeComponent();
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
Console.WriteLine("Path generated : {0}", UserName);
return ActivityExecutionStatus.Closed;
}
}
La seconde partie de ce post concerne la customisation du rendu de l'activité dans le workflow. Ainsi, pour faire propre ... il faut implémenter les classes de thème (ci-dessous) ... et les assigner en attribut au dessus de l'activité.
public sealed class GenerateNameActivityDesignerTheme : ActivityDesignerTheme
{
public GenerateNameActivityDesignerTheme(WorkflowTheme theme)
: base(theme)
{
this.BackColorStart = Color.LightGreen;
this.BackColorEnd = Color.Green;
}
}
[ActivityDesignerTheme(typeof(GenerateNameActivityDesignerTheme))]
public sealed class GenerateNameActivityDesigner : ActivityDesigner
{
protected override void Initialize(Activity activity)
{
base.Initialize(activity);
}
}
Après création de ces thèmes, le rendu du workflow est différent ;-)
Vous pouvez télécharger les sources via ce
lien.