Crear Custom Activities en WF
Como me ha tocado en el proyecto crear Custom Activities para WF voy a explicar como las he realizado.
Lo primero el usuario queria que las actividades quedasen reflejadas de un tamaño fijo y mas grande, que tuviese un color predeterminado por el, que el icono que habitualmente sale en las actividades no saliese y que el texto de la actividad saliese centrado. Esa fuerón las especificaciones que me dieron.
Para definir una Custom Activity en WF es bastante facil solo hay que derivar de la clase Activity y ya tenemos nuestra propia actividad. en esta clase podemos extenderla con las propiedades que necesitemos e interactuar con ella. Por ejemplo el siguiente código nos muestra una actividad
public class IdentificarLateralidadActivity : Activity
{
public string[] ActivityScreenControls;
private int _idPaso = 32;
public int IdPaso
{
get { return _idPaso; }
set { _idPaso = value; }
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
// Aqui se ejecuta la actividad, asi que tendriamos que lanzar un evento
// que permita capturar que se ejecuta, y mostrar la pantalla que desemos
return base.Execute(executionContext);
}
protected override void Initialize(IServiceProvider provider)
{
base.Initialize(provider);
this.Name = "Identificar Lateralidad";
this.Description = "";
}
protected override void InitializeProperties()
{
base.InitializeProperties();
}
protected override void OnActivityExecutionContextLoad(IServiceProvider provider)
{
base.OnActivityExecutionContextLoad(provider);
}
protected override void OnActivityExecutionContextUnload(IServiceProvider provider)
{
base.OnActivityExecutionContextUnload(provider);
}
protected override void OnClosed(IServiceProvider provider)
{
base.OnClosed(provider);
}
}
Pero con esto no cumplimos los requisitos del color, tamaño.. que nos puso el usuario. Para cumplir estos requisitos debo de implementar dos clases mas La primera debe derivar de la clase ActivityDesignerTheme y aqui especificaremso el color y algunas propiedades respecto al aspecto. En mi caso
public class MyActivityDesignerTheme : ActivityDesignerTheme
{
public MyActivityDesignerTheme(WorkflowTheme theme)
: base(theme)
{
}
public override void Initialize()
{
base.Initialize();
BorderColor = Color.FromArgb(251, 129, 6);
BorderStyle = DashStyle.Solid;
BackColorStart = Color.FromArgb(255, 128, 0);
BackColorEnd = Color.FromArgb(255, 236, 217);
BackgroundStyle = LinearGradientMode.ForwardDiagonal;
ForeColor = Color.Black;
}
}
La segunda clase debe derivar de ActivityDesigner en la que especificaremos el diseño, como el tamaño.. Esta clase debe hacer referencia a MyActivityDesignerTheme a través de un atributo [ActivityDesignerTheme(typeof(MyActivityDesignerTheme))] de manera que indicamos que el diseñador de actividades utilize el tema creado por mi. El código del diseñador
[ActivityDesignerTheme(typeof(MyActivityDesignerTheme))]
public class MyActivityDesigner : ActivityDesigner
{
//Damos un tamaño fijo a la actividad
readonly static Size BaseSize = new Size(200, 50);
//Quitamos el icono
protected override Rectangle ImageRectangle
{
get { return new Rectangle(new Point(0, 0), new Size(0, 0)); }
}
//Quitamos el texto
protected override Rectangle TextRectangle
{
get { return new Rectangle(new Point(0, 0), new Size(0, 0)); }
}
protected override void Initialize(Activity activity)
{
base.Initialize(activity);
}
//Retonornamos el tamaño fijo
protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs e)
{
base.OnLayoutSize(e);
return BaseSize;
}
//sobreescribimos el metodo OnPaint indicando que dibjue un texto con el tamaño
//de la actividad y centrado
protected override void OnPaint(ActivityDesignerPaintEventArgs e)
{
base.OnPaint(e);
Graphics graphics = e.Graphics;
MyActivityDesignerTheme compositeDesignerTheme = (MyActivityDesignerTheme)e.DesignerTheme;
string text = this.Text;
Rectangle textRectangle = this.Bounds;
ActivityDesignerPaint.DrawText(graphics, compositeDesignerTheme.Font, text, textRectangle, StringAlignment.Center, e.AmbientTheme.TextQuality, compositeDesignerTheme.ForegroundBrush);
}
}
Solo faltaria poner a la clase que he definido con la actividad el atributo
[DesignerAttribute(typeof(MyActivityDesigner), typeof(IDesigner))]
Indicando la clase de diseño que tiene que utilizar cuando dibuje esa actividad
De esta manera el resultado obtenido es
