通过自定义WPF组件中的context.ScheduleActivity()传递变量

时间:2019-08-29 18:37:34

标签: c# wpf wpf-controls workflow-foundation uipath

Windows Workflow Custom Sequence Activity的帮助下,我使用以下代码创建了一个模仿WPF中序列活动的活动。

using System.Activities;
using System.Activities.Statements;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace Custom_Activities
{
    [Designer("System.Activities.Core.Presentation.SequenceDesigner, System.Activities.Core.Presentation")]
    public class Scoped_Activity_Scope : NativeActivity
    {
        private string TestVariable = "testing testing";
        private Sequence innerSequence = new Sequence();

        [Browsable(false)]
        public Collection<Activity> Activities
        {
            get 
            {
                return innerSequence.Activities;
            }
        }

        [Browsable(false)]
        public Collection<Variable> Variables
        {
            get
            {
                return innerSequence.Variables;
            }
        }

        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            metadata.AddImplementationChild(innerSequence);
        }

        protected override void Execute(NativeActivityContext context)
        {
            System.Console.WriteLine("Scope Executing");
            context.ScheduleActivity(innerSequence);
        }

    }
}

我还在下面创建了第二个自定义活动

using System.Activities;

namespace Custom_Activities
{
    public sealed class Scoped_Activity : Scoped_Activity_Template
    {
        protected override void Execute(CodeActivityContext context)
        {
            System.Console.WriteLine("Scope Activity Executing");
            //System.Console.WriteLine(testVariable);
        }
    }
}

当我运行以下代码时

enter image description here

我得到了想要的输出

Scope Executing

Scope Activity Executing

如何按照注释的代码行从类testVariable中传递变量Scoped_Activity_Scope以便在Scoped_Activity中使用?

2 个答案:

答案 0 :(得分:1)

首先,您要为内部活动创建一个属性:

public string TestVariable { get; set; }

然后,您可以通过Activities集合访问该属性。

在两种情况下,您需要更新TestVariable的值:1,当TestVariable更改时,以及2,当您向Scoped_Activity添加新的Scoped_Activity_Scope

数字1很简单,每次更改父级的Scoped_Activity.TestVariable时只需更改所有TestVariable。 2号有点困难。您需要能够捕获每次在UI中更改CollectionChanged时都会触发的Activities事件。通过活动的设计者可以做到这一点。我认为您可能已经为该活动编写了一个定制设计器。

public Scoped_Activity_Scope_Designer()
{
    InitializeComponent();
    this.Loaded += AddCollectionChangedHandler;
}

private void AddCollectionChangedHandler(object sender, RoutedEventArgs e)
{
    var ownactivities = 
        ModelItem.Properties[nameof(Scoped_Activity_Scope.Activities)].Collection;
    ownactivities.CollectionChanged += AddTestVariable;
}

AddTestVariable内,只需更新TestVariable中每个活动的ownActivities属性,您需要再次检索该属性。


顺便说一句,您也可以通过调用父级来访问TestVariable,但是再次,您仍然需要在Scoped_Activity_Designer内执行此操作,这实际上是可以访问父级的那个。但是,Scoped_Activity_Designer不知道TestVariable的更新时间,也不知道何时调用execute以检索最新值。使用CollectionChanged可能是最好的方法。

这是您通过父级访问TestVariable的方式:

var dataContext = 
    Parent.GetValue(Scoped_Activity_Scope_Designer.DataContextProperty);
if (dataContext != null)
{
    var designer = (Scoped_Activity_Scope_Designer) dataContext;
    var scoped_activity_scope = (Scoped_Activity_Scope) designer.ModelItem.GetCurrentValue();
    var scoped_activity = (Scoped_Activity) ModelItem.GetCurrentValue();
    scoped_activity.TestVariable = scoped_activity_scope.TestVariable;
}

您应将此代码放在Scoped_Activity_Designer中的Loaded事件的处理程序中。

答案 1 :(得分:0)

Scoped_Activity_Scope方法内的Execute中,我添加了以下代码来迭代innerSequence中的活动

foreach(Activity a in innerSequence.Activities)
{
    if (a.GetType().IsSubclassOf(typeof(UiPath_Activities_Templates.Scoped_Activity_Template)))
    {
        Scoped_Activity_Template vet = null;
        vet = (Scoped_Activity_Template) a;
        vet.UpdateTestVariable("changed");
    }
}

在“ Scoped_Activity”继承的类“ Scoped_Activity_Template”中(该类以前为空),我添加了以下代码

public static string TestVariable = "testing";

public void UpdateTestVariable(string newValue)
{
    TestVariable = newValue;
}

这样,继承的类Scoped_Activity就可以访问变量TestVariable

当循环遍历innerSequence中的活动时,它将检查它是否继承自Scoped_Activity_Template,并调用方法UpdateTestVariable来更新变量。

然后执行类Scoped_Activity时,它将具有更新的变量。