Please ensure Javascript is enabled for purposes of website accessibility
Powered by Zoomin Software. For more details please contactZoomin

AVEVA™ Work Tasks

Configure Custom ASPX Property

  • Last UpdatedJun 10, 2024
  • 8 minute read

Using the AVEVA Work Tasks defined interfaces, custom ASPX property can be created that can be used in any of the custom activity where this property can be used. This custom ASPX property will be available in the Activity Properties of the custom activity which is using this property.

Procedure

Dll Reference

System.Web

Workflow.NET.NET2

Workflow.NET.Web.Designer.NET2

Namespace Used

System

System.IO

System.Xml

System.Xml.XPath

System.Collections.Generic

System.Text

Workflow.NET

Workflow.NET.Engine

Workflow.NET.Interfaces

Workflow.NET.Web.Designer.Interfaces;

To create a Custom ASPX Property

  1. Go to Start->Visual Studio 2005->New->Projects->Class Library->SampleCustomAspxProperty. This step will create a Class Library project in the path specified by the name SampleCustomAspxProperty.

  2. Create two class files SampleCustomASPXProperty.cs and SampleCustomASPXPropertyWebUI.cs under the project.

  3. There are two interfaces of AVEVA Work Tasks which will be used while developing a custom property.
    One is the IPropertyTypeWebUI interface and the other is the IPropertyType2 interface.

  4. The IPropertyTypeWebUI  interface is used to render the property in the Process Designer.

  5. The IPropertyType2 interface is used for setting and getting the details of the property. IPropertytype2 interface inherits the IpropertyType interface internally.

    SampleCustomASPXProperty.cs  Which Implements the IpropertyType2 Interface:

    using System;

    using System.IO;

    using System.Xml;

    using System.Xml.XPath;

    using System.Collections.Generic;

    using System.Text;

    using Workflow.NET;

    using Workflow.NET.Engine;

    using Workflow.NET.Interfaces ;

    namespace Workflow.NET.SampleAspxProperty

    {

    public class SampleCustomASPXPropertyType :IPropertyType2

    {


    public SampleCustomASPXPropertyType()

    {


    }


    string _defaultvalue;

    bool _mandatory;

    string _name;

     

    InitializationContext _contextInfo;



     

    #region IPropertyType2 Members



    /// <summary>

    /// This class provides the current running instance details of workflow at runtime

    /// (e.g : ContextInfo.CurrentContext.ExecutionID).

    /// This class is used in property for accessing the running details of workflow

    /// like applicationname,workflowname,currentcontext.

    /// </summary>


    public InitializationContext ContextInfo

    {

    get

    {

    return _contextInfo;

    }

    set

    {

    _contextInfo = value;

    }

    }


    #endregion



    string _dropDownValue = "";





    /// <summary>

    /// Drop down value captured from the ASPX page ui.

    /// </summary>


    public string DropDownValue

    {

    get

    {

    return _dropDownValue;

    }


    set

    {

    _dropDownValue = value;

    }


    }

     

    string _textBoxValue;


    /// <summary>

    /// Text box value captured from the ASXP page ui

    /// </summary>


    public string TextBoxValue

    {

    get

    {

    return _textBoxValue;

    }


    set

    {

    _textBoxValue = value;

    }


    }




    #region IPropertyType Members


    /// <summary>

    /// Clearing the value of the custom property.

    /// </summary>

    public void Clear()

    {

    _dropDownValue = "";

    if (string.IsNullOrEmpty(_defaultvalue))

    _dropDownValue = _defaultvalue;


    }


    /// <summary>

    /// Clones the property instance.

    /// Improper implementation of clone method could result in an unexpected value display.

    /// We have to make sure the required properties  are set from the clone method.

    /// </summary>

     

    public IPropertyType Clone()

    {

    SampleCustomASPXPropertyType oSampleAspxProperty = new SampleCustomASPXPropertyType();

    oSampleAspxProperty._mandatory = _mandatory;

    oSampleAspxProperty._defaultvalue = _defaultvalue;

    oSampleAspxProperty._name = _name;

    oSampleAspxProperty._dropDownValue = _dropDownValue;

    oSampleAspxProperty._textBoxValue = _textBoxValue;

     

    return oSampleAspxProperty;

    }


    /// <summary>

    /// Name of the Custom Property

    /// </summary>

    public string Name

    {

    get

    {

    return _name;

    }

    set

    {

    _name = value;

    }

    }


    /// <summary>


    /// If there is some definition which needs to be passed and read for initializing the property.

    /// The definition is defined along with the property in the actions.xml.

    ///</summary>

    public void ReadDefinitionXml(XmlTextReader xtr)

    {

    _defaultvalue = xtr.GetAttribute("defaultvalue");

    string mandatory = xtr.GetAttribute("mandatory");

    if (mandatory != null)  

    {


    if (mandatory.ToUpperInvariant() == "TRUE")

    _mandatory = true;

    else

    _mandatory = false;


    }



    ((IPropertyType)this).Clear();


    }

     

    /// <summary>

    /// The ReadXml method is called whenever the action which is having the property is loaded from process designer.

    /// The ReadXml method is also gets called when the property is getting accessed at the runtime.

    /// </summary>

     

    public void ReadXml(XmlTextReader xtr)

    {

    while (xtr.Read())

    {


    if (xtr.NodeType == XmlNodeType.EndElement && xtr.Name == "property") break;

    if (xtr.NodeType == XmlNodeType.EndElement && xtr.Name == "aspxproperty") break;

     

     

    if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "dropdownvalue")

    {

    _dropDownValue = xtr.ReadElementString();

    }

     

    if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "textboxvalue")

    {


    _textBoxValue = xtr.ReadElementString();


    }


    }


    }


    public override string ToString()

    {

    return Value;

    }


    public string ToString(string XPath)

    {

    throw new Exception("The method or operation is not implemented.");

    }


    public string ToString(bool ReturnXml)

    {

    throw new Exception("The method or operation is not implemented.");

    }


    /// <summary>

    ///  This property is used to set  or get the Value for the custom property.

    ///  Using this property the value of the property can be accessed at runtime.  

    /// </summary>

    public string Value

    {

    get

    {


    if (string.IsNullOrEmpty(_dropDownValue))

    {


    if (!string.IsNullOrEmpty(_defaultvalue))


    _dropDownValue = _defaultvalue;


    }


    return _dropDownValue;


    }


    set

    {


    string ErrorString = "";


    if (((IPropertyType)this).isValidValue(value, ref ErrorString))


    _dropDownValue = value;


    else


    throw new System.Exception(ErrorString);


    }


    }


    /// <summary>

    /// This method is used to write the property value data in the Process Definition in the XML format.

    /// This method will be called when the activity in which this property is used is rendered.

    /// This method is used to persist data which is saved after rendering the property in process designer

    /// and can be used in runtime.

    /// The value persisted here is read back from the ReadXml method of the IPropertytype interface.

    /// </summary>

    public void WriteXml(XmlTextWriter xtw)

    {

    xtw.WriteStartElement("aspxproperty");

    xtw.WriteStartElement("dropdownvalue");

    xtw.WriteCData(_dropDownValue);

    xtw.WriteEndElement();

    xtw.WriteStartElement("textboxvalue");

    xtw.WriteCData(_textBoxValue);

    xtw.WriteEndElement();

    xtw.WriteEndElement();  

    }


    /// <summary>

    /// Used to check the whether the property value is valid or not.

    /// The cross dependent validation can be done at the human activity level

    /// which has implemented the IValidateAction interface.

    /// </summary>

    /// <param name="Value">Property value</param>

    /// <param name="ErrorString">Error string returned if the value is not valid.</param>

    /// <returns>true or false</returns>

    public bool isValidValue(string Value, ref string ErrorString)

    {

    bool valid = false;


    if (_mandatory)

    {

    if (Value != null)

    {

    if (Value.Trim() != "")

    valid = true;


    }


    if (!valid)

    {

    if (ErrorString != null)


    ErrorString = "Value cannot be left empty [" + _name + "]";


    _dropDownValue = "";


    }


    }

    else

    valid = true;


    return valid;

    }


    #endregion

    }

    }

    SampleCustomASPXPropertyWebUI.cs  which implements the IPropertyTypeWebUI interface

    using System;

    using System.Web;

    using System.Web.UI;

    using System.Collections.Generic;

    using System.Text;

    using Workflow.NET.Web.Designer.Interfaces;

    using Workflow.NET.Web.Designer;

    using Workflow.NET;

    namespace Workflow.NET.SampleAspxProperty

    {

    /// <summary>

    /// Class which implements IPropertyTypeWebUI interface for rendering the custom property

    /// in the process designer when it is used within the Custom Activity.

    /// </summary>


     public class SampleCustomASPXPropertyWebUI :IPropertyTypeWebUI

    {

     public SampleCustomASPXPropertyWebUI()

     {


     }


    #region IPropertyTypeWebUI Members


     

     /// <summary>

     /// This method is used to render the UI for the Custom Aspx Property in the process designer.

     /// This method has the logic of specifying the custom aspx page which will open on click of the button.

     /// </summary>


     /// <param name="oAction">Action class details to which this custom property belongs.</param>

     /// <param name="oProperty">Property object which is used for getting value,name so that the value will be retained

     ///  if you are loading the action after setting the property value.</param>

     /// <param name="oWebDesigner">ProcessDesigner control to which the control used in the custom property is added.

     ///</param>

    public void Draw(Action oAction, Property oProperty, ProcessDesigner oWebDesigner)

    {

    string output;

    ProcessDesignerAdapter pda = new ProcessDesignerAdapter(oWebDesigner);

    //To get the workflow related Querystring Parameters.This method is used in ASPX property types which is getting opened from the Process Designer.

    string s = pda.GetUrlParameters(false);

    String URL = oWebDesigner.GetTemplateRelativeUrl("CustomAspx.aspx") + "?ActionName=" + Workflow.NET.CommonFunctions.HandleSplCharactersForLocalization(System.Web.HttpUtility.UrlEncode(oAction.Name)) + "&selPropertyName=" + Workflow.NET.CommonFunctions.HandleSplCharactersForLocalization(System.Web.HttpUtility.UrlEncode(oProperty.Name)) + "&" + s;


    output = "<TABLE class='propertiesboxinputstable' cellpadding=0 cellspacing=0 width=100%>";

    output += "<TR>";

    Workflow.NET.SampleAspxProperty.SampleCustomASPXPropertyType AspxPropertyType = ((Workflow.NET.SampleAspxProperty.SampleCustomASPXPropertyType)oProperty.PropertyHandler);


    string propValue = AspxPropertyType.Value;

    if (!string.IsNullOrEmpty(propValue))

    output += "<TD>" + CommonFunctions.AddElipses(System.Web.HttpUtility.HtmlEncode(propValue), 20) + "</TD>";

    else

    output += "<TD>" + CommonFunctions.AddElipses(oWebDesigner.ActionsDefinition.GlobalResourceSet.GetString("CustomASPXPropertyValue"), 20) + "</TD>";


    output += "<TD width=20><input type=button text=W class=propertiesboxinputbutton style=\"width:15;height:15\"  onclick=\"window.open('" + URL + "','AspxProperty','height=395,width=790,resizable=no');\"></TD>";


    output += "</TR>";

    output += "</TABLE>";

    oWebDesigner.Controls.Add(new LiteralControl(output));


    }


     public PropertyPage CreatePropertyPageInstance()

     {

     return null;

     }

     

    public bool HandlePostBack(Action oAction, Property oProperty, ProcessDesigner oWebDesigner, ref string ErrorString)

    {

    bool valid = false;

    ErrorString = "";

    if (oProperty.PropertyHandler.isValidValue(oProperty.Value.ToString(), ref ErrorString))

    {

    valid = true;

    }

    return valid;

    }


    #endregion

    }

    }

  6. Build the Project.

  7. Add the dll of the Project to the [AVEVA Work Tasks Installed Path]\AVEVA\Work Tasks\BPM.NET\bin and the [AVEVA Work Tasks Installed Path]\AVEVA\Work Tasks\BPM.NET\Web\EnterpriseConsole\bin

  8. Create an ASPX Page "CustomASPX.aspx" for showing the UI for the property.

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="CustomASPX.aspx.cs" Inherits="BPMUITemplates_Default_ProcessDesigner_CustomASPX" %>


    <html>


    <head id="Head1" runat="server">


    <title><%=sWorkflow%>-<%=actionname%>-<%=propertyname%></title>


    <link href="<%=ProcessDesignerControl.GetCommonRelativeUrl("stylesheet/global.css")%>" rel="stylesheet" type="text/css" />


    </head>


    <body>


    <form id="form1" runat="server">


    <br />


    <div>


    <table border="0" cellpadding="4" cellspacing="1" height="10%" width="100%" class='tablebg'>


    <tr>


    <td class="header2" colspan=2>

    <font class="subtitle">Custom ASPX Property</font>  

    </td>


    </tr>


    <tr bgcolor=white>


    <td style="width: 187px">


    <asp:Label ID="Label1" runat="server" Text="Label" CssClass="lefttdbg"><font class="subtitle">Select the value:</font></asp:Label>


    </td>


    <td>

    <asp:DropDownList ID="DropDownList1" runat="server" CssClass="inputselect"></asp:DropDownList><br />

    </td>


    </tr>


    <tr bgcolor=white>


    <td style="width: 187px">


    <asp:Label ID="Label2" runat="server" Text="Label" CssClass="lefttdbg"><font class="subtitle">Enter Value:</font> </asp:Label>


    </td>


    <td>


    <asp:TextBox ID="TextBox1" runat="server" CssClass="inputtext"></asp:TextBox>


     </td>


    </tr>


    <tr bgcolor=white>


    <td colspan=2 align=center>


    <asp:Button ID="Button1" runat="server" Text="Submit" CssClass="inputbutton" OnClick="Button1_Click"/>  


    </td>


    </tr>


    </table>


    <br />  


    </div>


    </form>


    </body>


    </html>

  9. Create a Codebehind file for Custom aspx page CustomASPX.aspx.cs

    using System;

    using System.Data;

    using System.Configuration;

    using System.Collections;

    using System.Web;

    using System.Web.Security;

    using System.Web.UI;

    using System.Web.UI.WebControls;

    using System.Web.UI.WebControls.WebParts;

    using System.Web.UI.HtmlControls;

    using Workflow.NET;

    using Workflow.NET.Web.Designer;

    public partial class BPMUITemplates_Default_ProcessDesigner_CustomASPX : System.Web.UI.Page

    {


    protected Property selProperty = null;


    protected ProcessDesigner ProcessDesignerControl;

    protected ProcessDesignerAdapter pda;

    protected string actionname = "";

    protected string propertyname = "";

    protected string sWorkflow = "";

     


    Workflow.NET.SampleAspxProperty.SampleCustomASPXPropertyType aspxProperty = null;


    /// <summary>

    /// Page Load Method.

    /// Reading the Querystring parameters passed from the Draw Method of the Custom ASPX Property.

    /// Filling of Drop down which is used in the Custom Aspx page.

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    protected void Page_Load(object sender, EventArgs e)

    {

     

    if (!Page.IsPostBack)

    {


    actionname = this.Context.Request["ActionName"];

    propertyname = this.Context.Request["selPropertyName"];

     


    this.ViewState["actionname"] = actionname;

    this.ViewState["selpropertyname"] = propertyname;

     


    }


    else

    {

    actionname = this.ViewState["actionname"].ToString();

    propertyname = this.ViewState["selpropertyname"].ToString();


    }


    pda = new ProcessDesignerAdapter();

     

    //To get the Process Designer details  corresponding to the current application name,workflow name. This can be used in the ASPX pages which is getting opened from the Process designer say menu .In the Code behind of ASPX page you will require workflow related details like Application Name,Workflow Name and which is the current action.

    pda.LoadControlInstance(false);

    ProcessDesignerControl = pda.ProcessDesignerControl;

    sWorkflow = pda.ProcessDesignerControl.WorkflowName;

    //Getting the Action Object from the Process Designer Control process definition object which contains

    //the details definition of the workflow by passing the action name

    Workflow.NET.Action selAction = ProcessDesignerControl.ProcessDefinition.Actions[actionname];

    //Getting the property details based on the property name passed from the action object

    selProperty = selAction.Properties[propertyname];

    aspxProperty = (Workflow.NET.SampleAspxProperty.SampleCustomASPXPropertyType)selProperty.PropertyHandler;


    if (!Page.IsPostBack)

    {


    if (!string.IsNullOrEmpty(aspxProperty.TextBoxValue))

     TextBox1.Text = aspxProperty.TextBoxValue;


    DropDownList1.Items.Add(new ListItem("Orange", "Orange"));

    DropDownList1.Items.Add(new ListItem("Yellow", "Yellow"));

    DropDownList1.Items.Add(new ListItem("Green", "Green"));

    DropDownList1.Items.Add(new ListItem("Blue", "Blue"));

    DropDownList1.Items.Add(new ListItem("White", "White"));


    if (!string.IsNullOrEmpty(aspxProperty.DropDownValue))

    {

    ListItem selectedItem = DropDownList1.Items.FindByValue(aspxProperty.DropDownValue);

    selectedItem.Selected = true;


    }

    }


    }


    /// <summary>

    /// On click Event handling of button

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    protected void Button1_Click(object sender, EventArgs e)

    {

    //Assigning to the Custom Property drop down value property with the selected

    //dropdown value shown in the custom ASPX page UI

    aspxProperty.DropDownValue = DropDownList1.SelectedItem.Value;

    //Assigning to the Custom Property text value with the text box value shown in the custom ASPX page UI

    aspxProperty.TextBoxValue = TextBox1.Text;


    //Writing the property values in the Xml format as defined per the WriteXML method of the Custom

    //Aspx property type

    ProcessDesignerControl.WriteFile();

    //To Refresh the Selected action so that the updated value appears in the property and closing the window which shows the custom aspx page UI.

    Response.Write("<script language='javascript'> window.setTimeout('window.opener.refreshselectedaction()',100);window.opener.parent._skProcessDesigner.RefreshProperties();window.setTimeout('window.close()',100); </script>");


    }


    }

  10. Copy the aspx page (CustomASPX.aspx and code behind) that is created to the web application BPMUITemplates\Default\ProcessDesigner folder. The sample is built to load the Custom ASPX page from this particular folder.

  11. Update the property in Actions.XML under <properties> tag. Add the following tag in actions.xml under <properties> tag.

    <propertytype name="SampleAspxProperty" classname="Workflow.NET.SampleAspxProperty.SampleCustomASPXPropertyType" assemblyname="Bin\SampleCustomAspxProperty.dll" webuiclassname="Workflow.NET.SampleAspxProperty.SampleCustomASPXPropertyWebUI" webuiassemblyname="Bin\SampleCustomAspxProperty.dll"/>

Now the property can be included in any custom activity under <properties> tag of Custom Activity.

For example:

<action name="CustomeActivity" displayname="Custom Activity">

<description>Custom Activity.</description>

<image resourcename="dummyaction.png"></image>

<handler classname="CustomeActivity.Class1" assembly="bin\CustomeActivity.dll"></handler>

<properties>

<property name="CustomActivity Property" type="aspxproperty"></property>

</properties>

</action>


Related Links
TitleResults for “How to create a CRG?”Also Available in