views:

43

answers:

0

I am currently in the process of writing a custom ActivityCondition to make it easy for an end user to setup a Condition on an IfElse Activity. When the user sets up the condition for one of the branches, they are presented with a Form to select a field and the value they want to match against. When the form is closed the Condition is automatically created for the user.

One of the properties in the Condition (Node) is an object which should point to the output from a previous Activity, if I manually setup the Condtion Property using the Properties pane in the designer, the Node Property will correctly bind to a Node object that I selected - but I have been unable to get this binding to happen by creating the Condition in code.

The ActivityCondtion class definition is (with the properties removed for brevity):

public class DoesFieldValueMatch : ActivityCondition
{
    #region Dependency Properties

    public static readonly DependencyProperty NodeProperty;
    public static readonly DependencyProperty FieldNameProperty;
    public static readonly DependencyProperty FieldValueProperty;

    #endregion

    static DoesFieldValueMatch()
    {
        NodeProperty = DependencyProperty.Register("Node", typeof(Node), typeof(DoesFieldValueMatch), new PropertyMetadata(null, DependencyPropertyOptions.Default, new Attribute[] { new ValidationOptionAttribute(ValidationOption.Required) }));
        FieldNameProperty = DependencyProperty.Register("FieldName", typeof(string), typeof(DoesFieldValueMatch), new PropertyMetadata(null, DependencyPropertyOptions.Default, new Attribute[] { new ValidationOptionAttribute(ValidationOption.Required) }));
        FieldValueProperty = DependencyProperty.Register("FieldValue", typeof(string), typeof(DoesFieldValueMatch), new PropertyMetadata(null, DependencyPropertyOptions.Default, new Attribute[] { new ValidationOptionAttribute(ValidationOption.Required) }));
    }

    public override bool Evaluate(Activity activity, IServiceProvider provider)
    {
        foreach (var field in Node.Fields)
        {
            if (field.Name == FieldName && field.Value == FieldValue) return true;
        }
        return false;
    }
}

And my UITypeEditor class is defined as :

internal class FieldValueEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) 
    {
        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
    {
        var activity = context.Instance as ArchivingIfElseBranchActivity;

        using(var form = new FieldValueForm(activity))
        {
            form.ShowDialog();

            return new DoesFieldValueMatch
                       {
                           FieldName = form.FieldName,
                           Node = (activity.Parent as ProcessItemWithinLoopActivity).Node,
                           FieldValue = form.FieldValue
                       };
        }
    }

    public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context) 
    {
        return false;
    }
}

The Node assignment is hardcoded currently to try to get this to work, but with the above code, the Node Property is not getting bound like it does when I select it using the Properties designer, it uses the value of the Node property rather than a reference to it.

Is it possible to bind a property to another activities property in code like this?