Activity无法在其范围内设置变量?

时间:2011-06-08 21:04:06

标签: .net variables workflow-foundation-4

这个让我挠头,我想知道我是否正确理解这一点。

我正在尝试在子活动可以使用的Activity中定义变量。 Parent应该能够在运行时在此变量中设置一个值。

这是剥离的父类:

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:   家长”。活动只能访问   它自己的实现变量。

问题在于我需要将值传递给我的子项,它们可以在设计时绑定到它们。这意味着无论什么保持价值必须在儿童活动的智能感知中可见。我能想到的唯一方法是定义一个像上面这样的变量,或者在父变量上创建一个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不同,因为绑定计算为{{ 1}}。

第二种方法是从Variables集合中获取变量并进行设置。

null

这会导致抛出相同的异常。我无法触及我自己范围内定义的变量。

2 个答案:

答案 0 :(得分:1)

您需要使用ActivityAction来包装需要访问同一变量的子活动并将其传递到那里。需要使用NativeActivityMetadata.AddImplementationVariable将变量本身添加到父活动本身可以像操作一样操纵它。就像ForEach这样的活动也在这样做。

有关详细信息,请参阅我的博文here

答案 1 :(得分:1)

老问题,但既然我在寻找解决方案,也许别人还在寻找......

我找到了一种方法,可以使用context.DataContext。

在原始示例中,替换;

var input = Variables.First(x => x.Name == "ThisIsTheVariable"); 
input.Set(context, "This is the Value");

用;

var input = context.DataContext.GetProperties()["ThisIsTheVariable"];
input.SetValue(context.DataContext, "This is the Value");