ExpressionTextBox 101

The ExpressionTextBox is the basic building block for editing expressions in custom activity designers. If you’re writing a custom activity designer that uses expressions, you’ll use this control. This post is meant to provide an overview for custom activity designer developers. I’m just going to annotate a small amount of the SDK sample and walk through it step by gory step. For those with short attention spans, skip this post and just take a look at the ExpressionTextBox SDK sample instead.   

Start with a new activity designer, and make sure you have the following namespaces available:

<sap:ActivityDesigner x:Class="Microsoft.Samples.ExpressionTextBoxSample.MultiAssignDesigner"

Expressions are bound to arguments using the ArgumentToExpressionConverter*, which is in the System.Activities.Presentation.Converters namespace.  Add this converter to your resource dictionary, like so:

<sapc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />

Now you can go on to adding your ExpressionTextBox. First, you need to figure out which type of expression you are editing. You can edit two types of expressions inside of an ExpressionTextBox, location expressions (or L-value expressions) and value expressions. Value expressions do what they say on the box. They are expressions that evaluate to a value, and you can place them on the right hand side of an assignment statement. InArguments correspond to value expressions, and are serialized as VisualBasicValue expressions (shortened to [] when serialized from the designer). Now, let’s pretend we have an activity with an InArgument named FooValue of type String. Here is a simplified ExpressionTextBox that binds to that argument:

Expression="{Binding Path=ModelItem.FooValue,
Converter={StaticResource ArgumentToExpressionConverter},
ConverterParameter=In }"

OwnerActivity="{Binding Path=ModelItem}"

Obviously, you’d set other properties in the real world, but the two that you absolutely must set are Expression and OwnerActivity. It is important to set ExpressionType as well, otherwise you will see some wonky behavior. Take a look at that expression binding – Path is to the argument to which you are binding, mode is almost always TwoWay, and then we pass the In parameter to the ArgumentToExpressionConverter to tell it that we are binding to an InArgument.

Conversely, location expressions correspond to OutArguments and are serialized as VisualBasicReference expressions (shortened to [] when serialized from the designer). You can put a location expression on the left hand side of an assignment statement. Now, let’s pretend we have an activity with an OutArgument named FooReference of type String. Here is a simplified ExpressionTextBox to bind to that argument.

Expression="{Binding Path=ModelItem.FooReference,
Converter={StaticResource ArgumentToExpressionConverter},
ConverterParameter=Out }"

OwnerActivity="{Binding Path=ModelItem}"

There are two differences from the previous example. Since we are binding to a L-value expression, the UseLocationExpression property is True. Because we are binding to an OutArgument, the ConverterParameter is Out.

Not shown today: binding ExpressionTextBoxes to CLR properties and binding to untyped arguments. Those will be subjects of another post.

*Aside – this is the only convenient converter for binding basic UI elements to arguments (WorkflowItem[s]Presenter excepted). In this release, you have to write your own converter to bind say a check box to a boolean argument.

Comments (8)
  1. WillSullivan says:

    How would you bind an expression textbox to a regular POCO property of an Activity?

  2. MarcinNajder says:


    Can I use ExpressionTextBox as an editor of System.Linq.Expressions.Expression type? If not, think about it, I believe you are really close to make it work this way.


  3. Hi Marcin, yes you can use System.Linq.Expressions.Expression as the type. Just add the appropriate namespace xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core" and then change the type above to sle:Expression. I even checked that this works at runtime if you have a variable of that type and you assign a value of say a NewExpression to it.

    Hi Will, I will work up a blog post with that sample shortly.


  4. MarcinNajder says:


    I think I was quite unprecise in my question 🙂 I have just started a new project in WPF ( and I want to use an ExpressionTextBox control as an editor for VB code. It is a very simple WPF application that has nothing to do with WF. I want to define some "referenced" assemblies (with namespaces),  set expression type, probably set some "This" object instance and that I’d like to be able to write a VB expression for example LINQ query. So the key point here is to not be depend on any WF stuff in ExpressionTextBox API such as activities, activities designers model and so on.

  5. Sorry that won’t work. You might consider Actpro Software Syntax Editor as an alternative.

  6. NoamFerrara says:

    Hi cathyk,

    I have implemented a custom expression editor

    In order to execute my custom expressions I need that the related ExpressionTextBox will be converted/ serialized to my own CustomExpressionValue activity instead of VisualBaisValue activity.

    It can be done by implementing a custom converter, and use it instead of the out of the box ArgumentToExpressionConverter.

    My problem is that I can do it only for my custom activities, but not for the others WF4 out of the box activities that use ExpressionTextBox, since this type of conversion is specified explicitly in their designer.

    Is there any way to convert an ExpressionTextBox used by WF4 out of the box activity to custom activity instead of VisualBasicValue activity?



  7. Paolo says:

    Hi Noam,

    I just wanted to let you know that in the designer metadata you can specify an editor of your own for properties. If the item you want is on the designer then you'll have to write your own designer, otherwise you can do as follows.

    builder.AddCustomAttributes(typeof(FlowSwitch<>), "Expression", new EditorAttribute(typeof(Editors.ActivityDialogExpressionEditor), typeof(DialogPropertyValueEditor)));

    public class ActivityDialogExpressionEditor : DialogPropertyValueEditor


           public ActivityDialogExpressionEditor()


               this.InlineEditorTemplate = new DataTemplate();

               FrameworkElementFactory stack = new FrameworkElementFactory(typeof(StackPanel));

               FrameworkElementFactory textBox = new FrameworkElementFactory(typeof(ExpressionTextBox));

               textBox.SetValue(ExpressionTextBox.HintTextProperty, "Paolo's Expression");

               //textBox.SetValue(ExpressionTextBox.UseLocationExpressionProperty, true);

               //textBox.SetValue(ExpressionTextBox.IsReadOnlyProperty, false);

               //Expression Type Binding

               Binding expressionTypeBinding = new Binding("ParentProperty.PropertyType");

               expressionTypeBinding.Converter = new TypeToArgumentTypeConverter();

               textBox.SetValue(ExpressionTextBox.ExpressionTypeProperty, expressionTypeBinding);

               //Owner Activity Binding

               Binding ownerActivityBinding = new Binding("ParentProperty");

               ownerActivityBinding.Converter = new ModelPropertyEntryToOwnerActivityConverter();

               ownerActivityBinding.Mode = BindingMode.OneWay;

               textBox.SetValue(ExpressionTextBox.OwnerActivityProperty, ownerActivityBinding);

               MultiBinding expressionBinding = new MultiBinding();

               Binding valueBinding = new Binding("Value");

               valueBinding.Mode = BindingMode.TwoWay;

               Binding propertyBinding = new Binding("ParentProperty");

               propertyBinding.Mode = BindingMode.OneWay;



               expressionBinding.Converter = new RulesEngineExpressionConverter(new ObjectToModelValueConverter());

               textBox.SetValue(ExpressionTextBox.ExpressionProperty, expressionBinding);

               stack.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);


               FrameworkElementFactory editModeSwitch = new FrameworkElementFactory(typeof(EditModeSwitchButton));

               editModeSwitch.SetValue(EditModeSwitchButton.TargetEditModeProperty, PropertyContainerEditMode.Dialog);


               this.InlineEditorTemplate.VisualTree = stack;


           public override void ShowDialog(PropertyValue propertyValue, IInputElement commandSource)


               Window window = new Window()


                   Title = "Expression Editor",

                   Content = new ActivityExpressionEditorControl(propertyValue)




    The editor above shows the code to generate an inline property editor and opens a usercontrol as the dialog editor. We are using this successfully to create our own property editors in place of the standard ones.



  8. Robert H. says:

    Cathy is it possible to declaratively implement an Expressiontextbox control in Xaml without binding to an ModelItem and reference the control value in the code behind?

Comments are closed.

Skip to main content