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
Excelente trabajo !!! Oskar
Ahora un par de preguntas:
1) Como se hace si le quiero agregar una imagen a la actividad
2) Como hago para hacer de esa actividad un componente y que aparezca en el ToolBox del Visual Studio al momento de diseñar un Workflow?
Hola, hoy vamos a ver como crear nuestras propias activities en detalle. No me voy a detener en como