SDK
最新
False
横幅背景图像
开发者指南
上次更新日期 2024年3月23日

编写活动代码

为了举例说明如何编写活动代码,我们将重新创建一个简单的“计算器”活动,该活动包含在示例UiPath.Examples.Activities解决方案中,您可以从 GitHub 下载该解决方案。 此活动接受两个数字和一个运算(加、减、乘或除)作为输入,并返回所选运算的结果。

活动代码由两部分组成 - 活动逻辑和活动设计。

活动逻辑

UiPath.Activities.Template开始,我们将重命名该解决方案,并将所有相关文件和引用重命名为UiPath.Examples.Activities

  1. 将保存活动逻辑的文件从“ ActivityTemplate.cs ”重命名为“ Calcerator.cs ”。
  2. 按如下方式更新引用和命名空间:

    using System.Activities;
    using System.Diagnostics;
    using UiPath.Examples.Activities.Helpers;
    
    namespace UiPath.Examples.Activities
    {
    }using System.Activities;
    using System.Diagnostics;
    using UiPath.Examples.Activities.Helpers;
    
    namespace UiPath.Examples.Activities
    {
    }
  3. 声明输入参数 - 两个数字(将FirstNumberSecondNumber声明为int )和要执行的操作(将SelectedOperation声明为enum ,并将可选默认值设置为Multiply )。 使用[RequiredArgument]属性将所有三个参数标记为必需。 返回的值将用于设置“结果”参数的值。
    public class Calculator : CodeActivity<int> // This base class exposes an OutArgument named Result
        {
            [RequiredArgument]
            public InArgument<int> FirstNumber { get; set; } //InArgument allows a varriable to be set from the workflow
    
            [RequiredArgument]
            public InArgument<int> SecondNumber { get; set; }
    
            [RequiredArgument]
            public Operation SelectedOperation { get; set; } = Operation.Multiply; // default value is optional
    
            /*
             * The returned value will be used to set the value of the Result argument
             */
        }    public class Calculator : CodeActivity<int> // This base class exposes an OutArgument named Result
        {
            [RequiredArgument]
            public InArgument<int> FirstNumber { get; set; } //InArgument allows a varriable to be set from the workflow
    
            [RequiredArgument]
            public InArgument<int> SecondNumber { get; set; }
    
            [RequiredArgument]
            public Operation SelectedOperation { get; set; } = Operation.Multiply; // default value is optional
    
            /*
             * The returned value will be used to set the value of the Result argument
             */
        }
  4. 启动执行部分,我们将添加日志记录,从工作流上下文中获取数字的值,并添加逻辑以处理除零的场景。

    protected override int Execute(CodeActivityContext context)
            {
                // This is how you can log messages from your activity. logs are sent to the Robot which will forward them to Orchestrator
                context.GetExecutorRuntime().LogMessage(new Robot.Activities.Api.LogMessage()
                {
                    EventType = TraceEventType.Information,
                    Message = "Executing Calculator activity"
                });
    
                var firstNumber = FirstNumber.Get(context); //get the value from the workflow context (remember, this can be a variable)
                var secondNumber = SecondNumber.Get(context);
    
                if (secondNumber == 0 && SelectedOperation == Operation.Divide)
                {
                    throw new DivideByZeroException("Second number should not be zero when the selected operation is divide");
                }
    
                return ExecuteInternal(firstNumber, secondNumber);
            } protected override int Execute(CodeActivityContext context)
            {
                // This is how you can log messages from your activity. logs are sent to the Robot which will forward them to Orchestrator
                context.GetExecutorRuntime().LogMessage(new Robot.Activities.Api.LogMessage()
                {
                    EventType = TraceEventType.Information,
                    Message = "Executing Calculator activity"
                });
    
                var firstNumber = FirstNumber.Get(context); //get the value from the workflow context (remember, this can be a variable)
                var secondNumber = SecondNumber.Get(context);
    
                if (secondNumber == 0 && SelectedOperation == Operation.Divide)
                {
                    throw new DivideByZeroException("Second number should not be zero when the selected operation is divide");
                }
    
                return ExecuteInternal(firstNumber, secondNumber);
            }
  5. 添加要为每个选定操作执行的计算。

    public int ExecuteInternal(int firstNumber, int secondNumber)
            {
                return SelectedOperation switch
                {
                    Operation.Add => firstNumber + secondNumber,
                    Operation.Subtract => firstNumber - secondNumber,
                    Operation.Multiply => firstNumber * secondNumber,
                    Operation.Divide => firstNumber / secondNumber,
                    _ => throw new NotSupportedException("Operation not supported"),
                };
            }        public int ExecuteInternal(int firstNumber, int secondNumber)
            {
                return SelectedOperation switch
                {
                    Operation.Add => firstNumber + secondNumber,
                    Operation.Subtract => firstNumber - secondNumber,
                    Operation.Multiply => firstNumber * secondNumber,
                    Operation.Divide => firstNumber / secondNumber,
                    _ => throw new NotSupportedException("Operation not supported"),
                };
            }
  6. 定义操作。

    public enum Operation
        {
            Add,
            Subtract,
            Multiply,
            Divide
        } public enum Operation
        {
            Add,
            Subtract,
            Multiply,
            Divide
        }

活动设计

活动中可用的输入由属性的数据类型决定。 在示例“计算器”活动中, 和int 属性的FirstNumber SecondNumber数据类型会生成数字编辑器作为属性的输入字段,而对于具有Operation enum数据类型的 ,活动中将出现一个下拉菜单。

属性的标签和工具提示可以在文件Resources.resx中定义。

下表描述了每个活动属性可用的最常见属性。

属性描述
显示名称属性的标签。
工具提示将鼠标指针悬停在属性上时显示的文本
是必填项1该属性是否为必填项。 还必须在活动中使用[RequiredArgument]属性标记必需属性。
是主体2属性在活动的主类别中是否应始终可见。 如果设置为false ,则该属性将显示在默认折叠的“显示高级选项”菜单下。
订单索引属性的显示顺序。

1不适用于输出属性,这些属性绝不是必需的。

2按照约定,输出属性位于高级选项下活动的末尾。

为“计算器”活动创建设计

  1. 将“ ActivityTemplateViewModel.cs ”文件重命名为“ CalceratorViewModel.cs ”,并向其中添加活动用户界面的代码。
  2. 按如下方式更新引用和命名空间:

    using System.Activities.DesignViewModels;
    using System.Diagnostics;
    
    namespace UiPath.Examples.Activities.ViewModels
    {
    }using System.Activities.DesignViewModels;
    using System.Diagnostics;
    
    namespace UiPath.Examples.Activities.ViewModels
    {
    }
  3. 声明输入属性。 结果属性来自活动的基类。 名称和类型参数必须与活动中的参数匹配。

    public class CalculatorViewModel : DesignPropertiesViewModel
        {
            /*
             * Properties names must match the names and generic type arguments of the properties in the activity
             * Use DesignInArgument for properties that accept a variable
             */
            public DesignInArgument<int> FirstNumber { get; set; }
            public DesignInArgument<int> SecondNumber { get; set; }
            /*
             * Use DesignProperty for properties that accept a constant value                
             */
            public DesignProperty<Operation> SelectedOperation { get; set; }
             /*
             * The result property comes from the activity's base class
             */
            public DesignOutArgument<int> Result { get; set; }
            
            public CalculatorViewModel(IDesignServices services) : base(services)
            {
            }
        }public class CalculatorViewModel : DesignPropertiesViewModel
        {
            /*
             * Properties names must match the names and generic type arguments of the properties in the activity
             * Use DesignInArgument for properties that accept a variable
             */
            public DesignInArgument<int> FirstNumber { get; set; }
            public DesignInArgument<int> SecondNumber { get; set; }
            /*
             * Use DesignProperty for properties that accept a constant value                
             */
            public DesignProperty<Operation> SelectedOperation { get; set; }
             /*
             * The result property comes from the activity's base class
             */
            public DesignOutArgument<int> Result { get; set; }
            
            public CalculatorViewModel(IDesignServices services) : base(services)
            {
            }
        }
  4. 添加活动设计代码。 (可选)我们可以通过取消注释包含Debugger.Break();的行来添加断点以调试视图模型初始化。 我们将初始化视图模型的属性,添加在初始化期间更改属性值时必需的PersistValuesChangedDuringInit()调用,并定义活动的输入和输出属性。

    代码应如下所示:

    protected override void InitializeModel()
            {
               //Debugger.Break(); 
                /*
                 * The base call will initialize the properties of the view model with the values from the xaml or with the default values from the activity
                 */
                base.InitializeModel();
    
                PersistValuesChangedDuringInit(); // just for heads-up here; it's a mandatory call only when you change the values of properties during initialization
    
                var orderIndex = 0;
    
                FirstNumber.DisplayName = Resources.Calculator_FirstNumber_DisplayName;
                FirstNumber.Tooltip = Resources.Calculator_FirstNumber_Tooltip;
                /*
                 * Required fields will automatically raise validation errors when empty.
                 * Unless you do custom validation, required activity properties should be marked as such both in the view model and in the activity:
                 *   -> in the view model use the IsRequired property
                 *   -> in the activity use the [RequiredArgument] attribute.
                 */
                FirstNumber.IsRequired = true;
    
                FirstNumber.IsPrincipal = true; // specifies if it belongs to the main category (which cannot be collapsed)
                FirstNumber.OrderIndex = orderIndex++; // indicates the order in which the fields appear in the designer (i.e. the line number);
    
                SecondNumber.DisplayName = Resources.Calculator_SecondNumber_DisplayName;
                SecondNumber.Tooltip = Resources.Calculator_SecondNumber_Tooltip;
                SecondNumber.IsRequired = true;
                SecondNumber.IsPrincipal = true;
                SecondNumber.OrderIndex = orderIndex++;
    
                SelectedOperation.DisplayName = Resources.Calculator_SelectedOperation_DisplayName;
                SelectedOperation.Tooltip = Resources.Calculator_SelectedOperation_Tooltip;
                SelectedOperation.IsRequired = true;
                SelectedOperation.IsPrincipal = true;
                SelectedOperation.OrderIndex = orderIndex++;
    
                /*
                 * Output properties are never mandatory.
                 * By convention, they are not principal and they are placed at the end of the activity.
                 */
                Result.DisplayName = Resources.Calculator_Result_DisplayName;
                Result.Tooltip = Resources.Calculator_Result_Tooltip;
                Result.OrderIndex = orderIndex;
            } protected override void InitializeModel()
            {
               //Debugger.Break(); 
                /*
                 * The base call will initialize the properties of the view model with the values from the xaml or with the default values from the activity
                 */
                base.InitializeModel();
    
                PersistValuesChangedDuringInit(); // just for heads-up here; it's a mandatory call only when you change the values of properties during initialization
    
                var orderIndex = 0;
    
                FirstNumber.DisplayName = Resources.Calculator_FirstNumber_DisplayName;
                FirstNumber.Tooltip = Resources.Calculator_FirstNumber_Tooltip;
                /*
                 * Required fields will automatically raise validation errors when empty.
                 * Unless you do custom validation, required activity properties should be marked as such both in the view model and in the activity:
                 *   -> in the view model use the IsRequired property
                 *   -> in the activity use the [RequiredArgument] attribute.
                 */
                FirstNumber.IsRequired = true;
    
                FirstNumber.IsPrincipal = true; // specifies if it belongs to the main category (which cannot be collapsed)
                FirstNumber.OrderIndex = orderIndex++; // indicates the order in which the fields appear in the designer (i.e. the line number);
    
                SecondNumber.DisplayName = Resources.Calculator_SecondNumber_DisplayName;
                SecondNumber.Tooltip = Resources.Calculator_SecondNumber_Tooltip;
                SecondNumber.IsRequired = true;
                SecondNumber.IsPrincipal = true;
                SecondNumber.OrderIndex = orderIndex++;
    
                SelectedOperation.DisplayName = Resources.Calculator_SelectedOperation_DisplayName;
                SelectedOperation.Tooltip = Resources.Calculator_SelectedOperation_Tooltip;
                SelectedOperation.IsRequired = true;
                SelectedOperation.IsPrincipal = true;
                SelectedOperation.OrderIndex = orderIndex++;
    
                /*
                 * Output properties are never mandatory.
                 * By convention, they are not principal and they are placed at the end of the activity.
                 */
                Result.DisplayName = Resources.Calculator_Result_DisplayName;
                Result.Tooltip = Resources.Calculator_Result_Tooltip;
                Result.OrderIndex = orderIndex;
            }
  5. 在文件Resources.resx中为标签和工具提示添加字符串值,如下图所示。 出于本地化目的,您必须为活动名称 ( Activity name ) 和活动说明 ( Activity description ) 使用特定注释。 对于其他字符串,建议添加注释,但并非强制性要求。


在 Studio 中,配置将导致以下结果:



1 - 三个输入属性的标签(显示名称)。

2 - FirstNumber属性的工具提示。
  • 活动逻辑
  • 活动设计
  • 为“计算器”活动创建设计

此页面是否有帮助?

获取您需要的帮助
了解 RPA - 自动化课程
UiPath Community 论坛
Uipath 白色徽标
信任与安全
© 2005-2024 UiPath. All rights reserved.