How to use custom ActivityCondition or filter which ActivityConditions are available

If you have your own custom ActivityCondition you are only going to be able to use it with your custom activities, not out of the box activities like While or IfElseBranch. First start by creating your custom ActivityCondition like the following:

[DisplayName("Custom Activity Condition")]

public class CustomActivityCondition : ActivityCondition

{

    public override bool Evaluate(Activity activity, IServiceProvider provider)

    {

        return (this.customCondition.Equals("foo", StringComparison.CurrentCultureIgnoreCase));

    }

    private string customCondition = string.Empty;

    public string CustomCondition

    {

        get{ return this.customCondition; }

  set{ this.customCondition = value; }

    }

}

Next create a custom TypeConverter that will add your activity condition to the list of available activity conditions for your user to select like below:

public class CustomActivityConditionTypeConverter : TypeConverter

{

    private Hashtable conditionDecls = new Hashtable();

    public CustomActivityConditionTypeConverter()

    {

        AddTypeToHashTable(typeof(RuleConditionReference));

        AddTypeToHashTable(typeof(CodeCondition));

        AddTypeToHashTable(typeof(CustomActivityCondition));

    }

    private void AddTypeToHashTable(Type typeToAdd)

    {

        string key = typeToAdd.FullName;

        object[] attributes = typeToAdd.GetCustomAttributes(typeof(DisplayNameAttribute), false);

        if (attributes != null && attributes.Length > 0 && attributes[0] is DisplayNameAttribute)

            key = ((DisplayNameAttribute)attributes[0]).DisplayName;

        this.conditionDecls.Add(key, typeToAdd);

    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)

    {

        if (sourceType == typeof(string))

            return true;

        return base.CanConvertFrom(context, sourceType);

    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)

    {

        if (value is string)

        {

            if (((string)value).Length == 0 || ((string)value) == "(None)")

                return null;

            else

                return Activator.CreateInstance(this.conditionDecls[value] as Type);

        }

        return base.ConvertFrom(context, culture, value);

    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)

    {

        if (destinationType == typeof(string))

            return true;

        else

            return base.CanConvertTo(context, destinationType);

    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)

    {

        if (value == null)

            return "(None)";

        object convertedValue = null;

        if (destinationType == typeof(string) && value is ActivityCondition)

        {

            foreach (DictionaryEntry conditionTypeEntry in this.conditionDecls)

            {

                if (value.GetType() == conditionTypeEntry.Value)

                {

                    convertedValue = conditionTypeEntry.Key;

                    break;

                }

            }

        }

        if (convertedValue == null)

            convertedValue = base.ConvertTo(context, culture, value, destinationType);

        return convertedValue;

    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)

    {

        ArrayList conditionDeclList = new ArrayList();

        conditionDeclList.Add(null);

        foreach (object key in this.conditionDecls.Keys)

        {

            Type declType = this.conditionDecls[key] as Type;

            conditionDeclList.Add(Activator.CreateInstance(declType));

        }

        return new StandardValuesCollection((ActivityCondition[])conditionDeclList.ToArray(typeof(ActivityCondition)));

    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)

    {

        return true;

    }

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)

    {

  return true;

    }

    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)

    {

        PropertyDescriptorCollection props = new PropertyDescriptorCollection(new PropertyDescriptor[] { });

        TypeConverter typeConverter = TypeDescriptor.GetConverter(value.GetType());

        if (typeConverter != null && typeConverter.GetType() != GetType() && typeConverter.GetPropertiesSupported())

        {

            return typeConverter.GetProperties(context, value, attributes);

        }

        return props;

    }

    public override bool GetPropertiesSupported(ITypeDescriptorContext context)

    {

        return true;

    }

Then to use your custom type converter you just need to add the TypeConverterAttribute to any properties that are ActivityCondition like below:

[Browsable(true)]

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

[TypeConverter(typeof(CustomActivityConditionTypeConverter))]

public ActivityCondition MyCustomCondition

{

    get

    {

        return ((ActivityCondition)(base.GetValue(CustomActivityWithCustomActivityCondition.MyCustomConditionProperty)));

    }

    set

    {

        base.SetValue(CustomActivityWithCustomActivityCondition.MyCustomConditionProperty, value);

    }

}

To filter the types of ActivityCondition that can be used update the type converter’s constructor to add only the types you want to use like the following which will only display RuleConditionReference and the custom activity condition:

public CustomActivityConditionTypeConverter()

{

    AddTypeToHashTable(typeof(RuleConditionReference));

    AddTypeToHashTable(typeof(CustomActivityCondition));

}

 

CustomActivityConditionExample.exe