Question

I have a solution which has a custom activity defined, and I made a designer to go along with it (see below). I have 3 projects, one for the custom activity, one for the designer for the custom activity, and a 3rd for actually running my custom activity (a simple console application).

When I create a composite activity that uses my custom activity, the designer in VS doesn't use my custom designer. I've ensured that the designer assembly is named with the *.Design.dll name and that it's copied to the console application's bin directory, but can't figure out why its not picking up my custom designer. Any ideas? Below is the code for all the necessary parts.

My Custom Activity

namespace WorkflowSampler.Activities
{
    using System.Activities;
    using System.Diagnostics;

    public class SampleVarChanger : NativeActivity
    {
        private InArgument<int> expressionToEvaluate;

        private Variable<int> counter;

        public Variable<int> Counter
        {
            get
            {
                return this.counter ?? (this.counter = new Variable<int>());
            }

            set
            {
                this.counter = value;
            }
        }

        public InArgument<int> ExpressionToEvaluate
        {
            get
            {
                return this.expressionToEvaluate ?? (this.expressionToEvaluate = new InArgument<int>());
            }

            set
            {
                this.expressionToEvaluate = value;
            }
        }

        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            metadata.AddImplementationVariable(this.Counter);

            var exprToEvalRuntimeArg = new RuntimeArgument("ExpressionToEvaluate", typeof(int), ArgumentDirection.In);
            metadata.Bind(this.ExpressionToEvaluate, exprToEvalRuntimeArg);
            metadata.AddArgument(exprToEvalRuntimeArg);
        }

        protected override void Execute(NativeActivityContext context)
        {
            Debug.WriteLine(string.Format("Counter Variable Value: {0}", this.Counter.Get(context)));
        }
    }
}

My Custom Activity's Designer (XAML Part)

<sap:ActivityDesigner x:Class="WorkflowSampler.Activities.Design.SampleVarChangerDesigner"
    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"
                      xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation">
    <sap:ActivityDesigner.Resources>
        <ResourceDictionary>
            <sapc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />
        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    <Grid Margin="10, 0, 0, 0">
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>

        <TextBlock Text="Variable Name:" VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" />
        <TextBox Name="VariableName" VerticalContentAlignment="Center" Grid.Row="0" Grid.Column="1" TextChanged="OnVariableNameChanged" />

        <TextBlock Text="Expression Using Variable:" VerticalAlignment="Center" Grid.Row="1" Grid.Column="0" />
        <sapv:ExpressionTextBox Name="ExpressionUsingVariable" VerticalContentAlignment="Center" Expression="{Binding Path=ModelItem.ExpressionToEvaluate, Converter={StaticResource ResourceKey=ArgumentToExpressionConverter}, ConverterParameter=In, Mode=TwoWay}" OwnerActivity="ModelItem" Grid.Row="1" Grid.Column="1" />
    </Grid>
</sap:ActivityDesigner>

My Custom Activity's Designer (Code Behind Part)

namespace WorkflowSampler.Activities.Design
{
    using System.Activities;
    // Interaction logic for SampleVarChangerDesigner.xaml
    public partial class SampleVarChangerDesigner
    {
        public SampleVarChangerDesigner()
        {
            InitializeComponent();
        }
        private void OnVariableNameChanged(object sender, TextChangedEventArgs e)
        {
            this.ModelItem.Properties["Counter"].SetValue(new Variable<int>(this.VariableName.Text));
        }
    }
}

The IRegisterMetadata Interface Required For VS Designer Support

namespace WorkflowSampler.Activities.Design
{
    using System.Activities.Presentation.Metadata;
    using System.ComponentModel;
    /// <summary>
    /// Registers the activity designer metadata.
    /// </summary>
    public class RegisterMetadata : IRegisterMetadata
    {
        public void Register()
        {
            AttributeTableBuilder builder = new AttributeTableBuilder();
            builder.AddCustomAttributes(typeof(SampleVarChanger), new DesignerAttribute(typeof(SampleVarChangerDesigner)));
            MetadataStore.AddAttributeTable(builder.CreateTable());
        }
    }
}
Was it helpful?

Solution

I figured it out... I need to have the design project copy out its DLL to the activity project, so what I did was create an MSBuild post build event to copy the design library over to the activity's debug folder. Now VS picks it up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top