在自定义 WPF 组件中通过 context.ScheduleActivity() 传递变量
Passing variable through context.ScheduleActivity() in custom WPF component
我在 Windows Workflow Custom Sequence Activity
的帮助下使用以下代码创建了一个 activity 来模仿 WPF 中的序列 activity
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);
}
}
}
我还在下面创建了第二个自定义 activity
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);
}
}
}
当我运行代码如下
我得到了想要的输出
Scope Executing
Scope Activity Executing
我如何根据注释掉的代码行从 class Scoped_Activity_Scope
传递变量 testVariable
以便在 Scoped_Activity
中使用?
首先你为内部 activity 创建一个 属性:
public string TestVariable { get; set; }
然后您可以通过 Activities
集合访问 属性。
有2种情况需要更新TestVariable
的值:1,当TestVariable
改变时,和2,当你添加一个新的Scoped_Activity
到[=17] =].
数字 1 很简单,每次更改 parent 的 TestVariable
时只需更改所有 Scoped_Activity.TestVariable
。 2 号有点困难。您需要能够捕获每次从 UI 更改 Activities
时触发的 CollectionChanged
事件。这可以通过 activity 的设计者实现。我假设您可能已经为 activity.
编写了自定义设计器
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
中,只需更新 ownActivities
中每个 activity 的 TestVariable
属性,您需要再次检索它。
顺便说一句,您也可以通过调用 Parent 来访问 TestVariable
,但是话又说回来,您仍然需要在 Scoped_Activity_Designer
内部执行此操作实际上可以访问 parent。但是,Scoped_Activity_Designer
不知道 TestVariable
何时更新,也不知道何时调用 execute 以检索最新值。使用 CollectionChanged
可能是最好的方法。
这就是您通过 parent:
访问 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 事件的处理程序中。
在 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");
}
}
并且在 class 'Scoped_Activity_Template' 中 'Scoped_Activity' 继承自(这个 class 之前是空的)我添加了以下代码
public static string TestVariable = "testing";
public void UpdateTestVariable(string newValue)
{
TestVariable = newValue;
}
这样继承的 class Scoped_Activity
就可以访问变量 TestVariable
.
当循环遍历 innerSequence
中的活动时,它会检查它是否继承自 Scoped_Activity_Template
,它会调用方法 UpdateTestVariable
来更新变量。
然后执行 class Scoped_Activity
时,它将具有更新的变量。
我在 Windows Workflow Custom Sequence Activity
的帮助下使用以下代码创建了一个 activity 来模仿 WPF 中的序列 activityusing 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);
}
}
}
我还在下面创建了第二个自定义 activity
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);
}
}
}
当我运行代码如下
我得到了想要的输出
Scope Executing
Scope Activity Executing
我如何根据注释掉的代码行从 class Scoped_Activity_Scope
传递变量 testVariable
以便在 Scoped_Activity
中使用?
首先你为内部 activity 创建一个 属性:
public string TestVariable { get; set; }
然后您可以通过 Activities
集合访问 属性。
有2种情况需要更新TestVariable
的值:1,当TestVariable
改变时,和2,当你添加一个新的Scoped_Activity
到[=17] =].
数字 1 很简单,每次更改 parent 的 TestVariable
时只需更改所有 Scoped_Activity.TestVariable
。 2 号有点困难。您需要能够捕获每次从 UI 更改 Activities
时触发的 CollectionChanged
事件。这可以通过 activity 的设计者实现。我假设您可能已经为 activity.
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
中,只需更新 ownActivities
中每个 activity 的 TestVariable
属性,您需要再次检索它。
顺便说一句,您也可以通过调用 Parent 来访问 TestVariable
,但是话又说回来,您仍然需要在 Scoped_Activity_Designer
内部执行此操作实际上可以访问 parent。但是,Scoped_Activity_Designer
不知道 TestVariable
何时更新,也不知道何时调用 execute 以检索最新值。使用 CollectionChanged
可能是最好的方法。
这就是您通过 parent:
访问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 事件的处理程序中。
在 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");
}
}
并且在 class 'Scoped_Activity_Template' 中 'Scoped_Activity' 继承自(这个 class 之前是空的)我添加了以下代码
public static string TestVariable = "testing";
public void UpdateTestVariable(string newValue)
{
TestVariable = newValue;
}
这样继承的 class Scoped_Activity
就可以访问变量 TestVariable
.
当循环遍历 innerSequence
中的活动时,它会检查它是否继承自 Scoped_Activity_Template
,它会调用方法 UpdateTestVariable
来更新变量。
然后执行 class Scoped_Activity
时,它将具有更新的变量。