问题
I want to create a composite Windows Workflow Activity (under .NET 4) that contains a predefined ReceiveAndSendReply Activity. Some of the properties are predefined, but others (particularly ServiceContractName) need to be set in the designer.
I could implement this as an Activity Template (the same way ReceiveAndSendReply is implemented), but would rather not. If I later change the template, I'd have to update all previously created workflows manually. A template would also permit other developers to change properties that should be fixed.
Is there a way to do this from a Xaml Activity? I have not found a way to assign an Argument value to a property of an embedded Activity. If not, what technique would you suggest?
回答1:
I haven't done this using a composite XAML activity and am getting some errors when I try but doing so through a NativeActivity is no problem. See the example code below.
public class MyReceiveAndSendReply : NativeActivity
{
    private Receive _receive;
    private SendReply _sendReply;
    public string ServiceContractName { get; set; }
    public string OperationName { get; set; }
    protected override bool CanInduceIdle
    {
        get { return true; }
    }
    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        _receive = _receive ?? new Receive();
        _sendReply = _sendReply ?? new SendReply();
        _receive.CanCreateInstance = true;
        metadata.AddImplementationChild(_receive);
        metadata.AddImplementationChild(_sendReply);
        _receive.ServiceContractName = ServiceContractName;
        _receive.OperationName = OperationName;
        var args = new ReceiveParametersContent();
        args.Parameters["firstName"] = new OutArgument<string>();
        _receive.Content = args;
        _sendReply.Request = _receive;
        var results = new SendParametersContent();
        results.Parameters["greeting"] = new InArgument<string>("Hello there");
        _sendReply.Content = results;
        base.CacheMetadata(metadata);
    }
    protected override void Execute(NativeActivityContext context)
    {
        context.ScheduleActivity(_receive, ReceiveCompleted);
    }
    private void ReceiveCompleted(NativeActivityContext context, ActivityInstance completedInstance)
    {
        context.ScheduleActivity(_sendReply);
    }
}
来源:https://stackoverflow.com/questions/4330310/setting-internal-properties-in-composite-wf4-activities-at-design-time