Activity 无法设置在其范围内定义的变量?
这让我摸不着头脑,我想知道我是否理解正确。
我试图在活动中定义一个可供子活动使用的变量。父级应该能够在运行时在此变量中设置一个值。
这是精简的父类:
public sealed class Parent : NativeActivity, IActivityTemplateFactory
{
public Collection<Child> Children { get; private set; }
private CompletionCallback<string> _cc;
private Variable<int> _index;
public Collection<Variable> Variables { get; private set; }
public Parent()
{
Children = new Collection<Child>();
_index = new Variable<int>();
_cc = new CompletionCallback<string>(OnComplete);
Variables = new Collection<Variable>();
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.AddImplementationVariable(_index);
metadata.SetVariablesCollection(Variables);
}
protected override void Execute(NativeActivityContext context)
{
_index.Set(context, 0);
var input = Variables.First(x => x.Name == "ThisIsTheVariable");
input.Set(context, "This is the Value");
context.ScheduleActivity(Children[0], _cc);
}
private void OnComplete(NativeActivityContext context, ActivityInstance instance, string result)
{
var index = _index.Get(context) + 1;
_index.Set(context, index);
Console.WriteLine(result);
if (index < Children.Count)
context.ScheduleActivity(Children[index], _cc);
}
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
var retval = new Parent();
retval.Variables.Add(new Variable<string>("ThisIsTheVariable"));
return retval;
}
}
现在,如果我将其添加到工作流程并运行它,我会得到以下极具讽刺意味的异常:
活动“1.1:家长”无法访问 这个变量,因为它被声明了 在活动范围'1.1: 父母'。一个Activity只能访问 它自己的实现变量。
问题是我需要将一个值传递给我的子活动,它们可以在设计时绑定到该值。这意味着任何持有该值的内容都必须在子 Activity 的智能感知中可见。我能想到的唯一方法是像上面一样定义一个变量,或者在父级上创建一个 OutArgument。第二种选择简直糟透了。
我该如何解决这个问题?
编辑
尝试对不起作用的变量进行一些处理。
我在我的父级中声明了一个变量:
// declaration
private Variable<string> _text;
// in ctor I create it
_text = new Variable<string>(InputName);
// in CacheMetadata I declare it an implementation variable
metadata.AddImplementationVariable(_text);
// in IActivityTemplateFactory.Create I add it to Variables
var retval = new Parent()
{
Input = new InArgument<string>()
};
retval.Variables.Add(retval._text);
return retval;
这一直有效到执行时间。该变量出现在设计界面中,我的子活动可以与其绑定。但我在运行时仍然无法触及它。我可以尝试通过两种方式执行此操作:
// set text via the implementation variable
protected override void Execute(NativeActivityContext context)
{
_text.Set(context, "DERP");
context.ScheduleActivity(Children[0], _cc);
}
这不会抛出异常,但子活动永远不会看到 DERP
,因为它们所绑定的变量实例显然与 不同_text
,因为绑定的计算结果为 null
。
第二种方法是从 Variables 集合中获取 Variable 并设置它。
protected override void Execute(NativeActivityContext context)
{
Variables.First().Set(context, "DERP");
context.ScheduleActivity(Children[0], _cc);
}
这会导致抛出相同的异常。我无法触及在我自己的范围内定义的变量。
This one is making me scratch my head, and I'm wondering if I am understanding this correctly.
I'm trying to define a Variable within an Activity that can be used by child Activities. The Parent should be able to set a value in this Variable at runtime.
Here's the stripped down Parent class:
public sealed class Parent : NativeActivity, IActivityTemplateFactory
{
public Collection<Child> Children { get; private set; }
private CompletionCallback<string> _cc;
private Variable<int> _index;
public Collection<Variable> Variables { get; private set; }
public Parent()
{
Children = new Collection<Child>();
_index = new Variable<int>();
_cc = new CompletionCallback<string>(OnComplete);
Variables = new Collection<Variable>();
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.AddImplementationVariable(_index);
metadata.SetVariablesCollection(Variables);
}
protected override void Execute(NativeActivityContext context)
{
_index.Set(context, 0);
var input = Variables.First(x => x.Name == "ThisIsTheVariable");
input.Set(context, "This is the Value");
context.ScheduleActivity(Children[0], _cc);
}
private void OnComplete(NativeActivityContext context, ActivityInstance instance, string result)
{
var index = _index.Get(context) + 1;
_index.Set(context, index);
Console.WriteLine(result);
if (index < Children.Count)
context.ScheduleActivity(Children[index], _cc);
}
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
var retval = new Parent();
retval.Variables.Add(new Variable<string>("ThisIsTheVariable"));
return retval;
}
}
Now, if I add this to a workflow and run it, I get the following highly ironic exception:
Activity '1.1: Parent' cannot access
this variable because it is declared
at the scope of activity '1.1:
Parent'. An activity can only access
its own implementation variables.
The problem is that I need to pass a value to my child Activities that they can bind to at design time. That means that whatever holds the value must be visible within the intellisense of the child Activities. The only ways I can think of doing this is to define a Variable like above, or create an OutArgument on the parent. The second option flat out sucks.
How can I get around this?
Edit
Tried to do a little trickery with the variable that didn't work.
I declared a variable within my Parent:
// declaration
private Variable<string> _text;
// in ctor I create it
_text = new Variable<string>(InputName);
// in CacheMetadata I declare it an implementation variable
metadata.AddImplementationVariable(_text);
// in IActivityTemplateFactory.Create I add it to Variables
var retval = new Parent()
{
Input = new InArgument<string>()
};
retval.Variables.Add(retval._text);
return retval;
This works up until execution time. The variable appears in the design surface and my child activities can bind against it. But I still can't touch it at runtime. I can attempt to do this two ways:
// set text via the implementation variable
protected override void Execute(NativeActivityContext context)
{
_text.Set(context, "DERP");
context.ScheduleActivity(Children[0], _cc);
}
This doesn't throw, but the child activities never see DERP
, as the instance of the Variable they are bound against apparently isn't the same as _text
as the binding evaluates to null
.
The second way is to grab the Variable from the Variables collection and set it.
protected override void Execute(NativeActivityContext context)
{
Variables.First().Set(context, "DERP");
context.ScheduleActivity(Children[0], _cc);
}
This results in the same exception being thrown. I can't touch a variable defined within my own scope.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要使用 ActivityAction 来包装子活动需要访问相同的变量并将其传递到那里。变量本身需要使用 NativeActivityMetadata.AddImplementationVariable 父活动本身可以像您正在做的那样操纵它。 ForEach 等活动也是这样做的。
请参阅我的博客文章此处了解更多详情。
You need to use an ActivityAction to wrap the child activities that need access to the same variable and pass it through there. The variable itself needs to be added using NativeActivityMetadata.AddImplementationVariable to the parent activity itself can manipulate it like you are doing. That is the way activities like the ForEach are doing it as well.
See my blog post here for more details.
老问题,但由于我正在寻找解决方案,也许其他人也在寻找......
我找到了一种使用 context.DataContext 来做到这一点的方法。
在您原来的示例中,替换;
和;
Old question, but since I was looking for a solution, maybe someone else is still looking too...
I found a way to do this using the context.DataContext.
In your original example, replace;
with;