WF4:NativeActivity 如何记住它的 children?

WF4: How does a NativeActivity remember its children?

所以,我在这里有点不知所措。我在 visual studio 2012 年创建了一个 WCF 工作流服务。如果我有一个 NativeActivity,其中公开了我使用设计器填写的 child 活动。它应该如何还记得我下次打开服务的 XAML 文件时那些 children 是什么吗?

我创建了一个 NativeActivity,其中一个 child 类型为 InvokeAction<String>(见下文)。我在初始化 object 时初始化 child,这似乎没问题。

我为此 activity 创建了一个自定义设计器,它只使用 WorkflowItemPresenter 来显示 child activity(见下文)。

当我在我的 WF 服务中添加一个 NativeActivity1 实例时,我看到我的自定义设计器 pre-populated 和我用来初始化它的 InvokeAction 实例。我在 InvokeAction activity 中添加了一些 child(例如,WriteLine),它显示出来了,一切似乎都很好。

我保存并构建,成功了。我关闭并重新打开 WF 服务设计器,然后... WriteLine 消失了。我检查了 WF 服务保存的 XAML,WriteLine activity 从未进入 XAML.

我的第一个想法是,这总是会发生,因为设计者调用 NativeActivity 的构造函数,它将 child 初始化为 child-less InvokeAction<String>

我不明白应该如何设置,因此在重新打开设计器时应保留此类信息。

我做错了什么?

NativeActivity1:

public sealed class NativeActivity1 : NativeActivity
{

    public InvokeAction<String> child = new InvokeAction<string>()
    {
        Argument = new InArgument<string>(CSharpValue<String>.FromValue("string literal")),
    };
    public InvokeAction<String> Child { get { return child; } }

    protected override void Execute(NativeActivityContext context)
    {
        context.ScheduleActivity(Child);
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddChild(Child);
    }
}

NativeActivity1Designer

<sap:ActivityDesigner x:Class="ActivityLibrary.VisualStudio.Design.NativeActivity1Designer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation">
<Grid>
    <sap:WorkflowItemPresenter Item="{Binding Path=ModelItem.Child, Mode=OneWay}"
                               Margin="5"
                               HintText="Drop Activity Here"/>
</Grid>

我似乎偶然发现了答案。

显然它只会尝试记住具有 public getter setter 的 children。因此,即使我不希望任何人更改与 child 关联的 InvokeAction<String> 的实例,它也需要是可设置的,否则 WF4 不会尝试记住它是什么。

您可以在 CacheMetadata 覆盖方法中添加需要您的子操作:

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
    if (this.TargetAction == null)
        metadata.AddValidationError("Target action is required.");
}

这样,设计人员将显示一个视觉对象,表明您的 activity 中缺少数据。这应该使它更正式。