views:

381

answers:

2

I'm creating an ActivityToolboxItem for a custom Activity in WF. I'm trying to do as much work as possible for the designers within the CreateComponentsCore method. What I'm trying to end up with is the following:

1) My custom activity (TriggerActivity, a SequenceActivity), containing the following:
2) A TriggerEvaluatorActivity (a simple Activity), which is bound to a property on the TriggerActivity
3) An IfElseActivity, which has two branches
4) An IfElseBranchActivity that contains
5) A TerminateActivity, and
6) An IfElseBranchActivity that is empty, through which execution flows when the TriggerEvaluatorActivity evaluates to true.

Designers switch out the TriggerEvaluatorActivity with one or more implementations that perform complex evaluations against an execution context.

Its pretty simple to set this up in code, but I'm completely stuck on how to spin up an ActivityCondition that will be added to the IfElseBranchActivity to control the flow of execution.

All I need to do is evaluate a property on the TriggerEvaluatorActivity. I've created a nice lovely Rule via the code dom, but I can't set that directly on the IfElseBranchActivity, I have to stash the rule somewhere and reference it in the activity.

So, I guess my question is, once I've created a rule in code, how do I add my rule to the workflow from within a custom ActivityToolboxItem so that the activities I build in code can reference it?

+1  A: 

According to this question on MSDN, its stored in a dependency property under the root Activity. Not sure if the code example is correct or not yet.


Works. Here's some sample code:

protected override System.ComponentModel.IComponent[] 
    CreateComponentsCore(System.ComponentModel.Design.IDesignerHost host)
{
    var trigger = new Trigger() { Name = "Trigger" };
    var never = new Never() { Name = "NeverTrigger" };
    var ifelse = new IfElseActivity() { Name = "IfElse" };
    var stop = new TerminateActivity() { Name = "StopJob" };
    var failed = new IfElseBranchActivity() { Name = "NotTriggered" };
    var succeeded = new IfElseBranchActivity() { Name = "Triggered" };
    // build tree
    failed.Activities.Add(stop);
    ifelse.Activities.Add(failed);
    ifelse.Activities.Add(succeeded);
    trigger.Activities.Add(never);
    trigger.Activities.Add(ifelse);
    // create rule if it doesn't already exist
    var ruleDefinitions = GetRuleDefinitions
        (host.RootComponent as DependencyObject);
    if (!ruleDefinitions.Conditions.Contains(RuleName))
    {
        var neverTrigger = 
            new CodePropertyReferenceExpression
                (new CodeThisReferenceExpression(), 
                "NeverTrigger");
        var triggered = 
            new CodePropertyReferenceExpression
                (neverTrigger, 
                "Triggered");
        var falseSide = new CodeBinaryOperatorExpression();
        falseSide.Left = triggered;
        falseSide.Right = new CodePrimitiveExpression(false);
        falseSide.Operator = CodeBinaryOperatorType.ValueEquality;

        var ruleCondition = new RuleExpressionCondition
            (RuleName, falseSide);


        ruleDefinitions.Conditions.Add(ruleCondition);
    }
    // add rule to the failed branch; 
    // don't need a rule for the succeeded branch
    failed.Condition = new RuleConditionReference() 
        { ConditionName = RuleName };

    return new IComponent[] { trigger };
}

private RuleDefinitions GetRuleDefinitions
    (DependencyObject rootComponent)
{
    var ruleDefinitions = rootComponent.GetValue
        (RuleDefinitions.RuleDefinitionsProperty) as RuleDefinitions;
    if (ruleDefinitions == null)
    {
        ruleDefinitions = new RuleDefinitions();
        rootComponent.SetValue(RuleDefinitions.RuleDefinitionsProperty, 
            ruleDefinitions);
    }
    return ruleDefinitions;
}
Will
Wow, self, that's pretty awesome. It works.
Will
Thanks, me. I get the feeling, however, that I'm missing something, as these rules I add are marked as invalid by the rule engine until they are VIEWED in the editor; after viewing them they are marked as valid. Weird.
Will
A: 

Will -

It may be that new rules are flagged until they have been validated. Did you see if you could directly validating them immediately after adding them?

kreinsch