marketplace
latest
false
UiPath logo, featuring letters U and I in white
Marketplace User Guide
Last updated Sep 5, 2024

The Designer File

Important: This document refers to a deprecated version of the UiPath Activity Creator for Visual Studio. Please see the new documentation here.

Intro

A complete activity may be created with the activity definition file alone, but the user experience is almost always enhanced by adding a designer, or UI. Designers are written in XAML, an XML-based language (described in more detail here), and used to create front-ends for Windows Presentation Foundation (WPF) applications.

Navigate to the ChildActivityDesigner.xaml file and walk through section by section to better understand how to enhance your activity with a UI.



<sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             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:converters="clr-namespace:UiPath.Shared.Activities.Design.Converters">
    <a href="sap:ActivityDesigner.Resources">sap:ActivityDesigner.Resources</a>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="..\)\)Themes\)\)Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <converters:ActivityIconConverter x:Key="ActivityIconConverter" />
        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    <a href="sap:ActivityDesigner.Icon">sap:ActivityDesigner.Icon</a>
        <DrawingBrush Stretch="Uniform" Drawing="{Binding Path=ModelItem, Converter={StaticResource ActivityIconConverter}, ConverterParameter=pack://application:\)\),\)\),\)\),/MyCompany.MyProduct.Activities.Design;component/themes/icons.xaml}" />
    </sap:ActivityDesigner.Icon>
</sap:ActivityDesigner><sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             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:converters="clr-namespace:UiPath.Shared.Activities.Design.Converters">
    <a href="sap:ActivityDesigner.Resources">sap:ActivityDesigner.Resources</a>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="..\)\)Themes\)\)Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <converters:ActivityIconConverter x:Key="ActivityIconConverter" />
        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    <a href="sap:ActivityDesigner.Icon">sap:ActivityDesigner.Icon</a>
        <DrawingBrush Stretch="Uniform" Drawing="{Binding Path=ModelItem, Converter={StaticResource ActivityIconConverter}, ConverterParameter=pack://application:\)\),\)\),\)\),/MyCompany.MyProduct.Activities.Design;component/themes/icons.xaml}" />
    </sap:ActivityDesigner.Icon>
</sap:ActivityDesigner>

Class Definition

All designers contain one top-level component in which a class is declared and supplemental namespaces are imported. This example extends the ActivityDesigner class, the base class for all such components.

<sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             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:converters="clr-namespace:UiPath.Shared.Activities.Design.Converters"><sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             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:converters="clr-namespace:UiPath.Shared.Activities.Design.Converters">
Notice that each of the namespaces imported takes the form xmlns:<prefix>. These prefixes are used later on in the file to reference useful components.

Resources

Resources are reusable components, styles, or data made available for use in a XAML file via a ResourceDictionary component. In this example, two types of resources are provided--a dictionary of styles (Generic.xaml) and a converter component (ActivityIconConverter).

<a href="sap:ActivityDesigner.Resources">sap:ActivityDesigner.Resources</a>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="..\)\)Themes\)\)Generic.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <converters:ActivityIconConverter x:Key="ActivityIconConverter" />
    </ResourceDictionary>
</sap:ActivityDesigner.Resources><a href="sap:ActivityDesigner.Resources">sap:ActivityDesigner.Resources</a>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="..\)\)Themes\)\)Generic.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <converters:ActivityIconConverter x:Key="ActivityIconConverter" />
    </ResourceDictionary>
</sap:ActivityDesigner.Resources>
  1. Generic.xaml is another ResourceDictionary containing standard UiPath styles that help keep the look of designers consistent. Peeking inside this file, you see the following style, which sets a standard height for all ComboBox objects. Because we've included this dictionary in our XAML file, all comboboxes will have a default height of 23px.
    <Style TargetType="{x:Type ComboBox}">
        <Setter Property="Height" Value="23" />
    </Style><Style TargetType="{x:Type ComboBox}">
        <Setter Property="Height" Value="23" />
    </Style>
  2. ActivityIconConverter is a utility class that is provided through the Shared folder and which allows all activity icons to be specified in a standard way. See the Icons section below for more details.



Icons



Icons, like those seen on all UiPath activities, may be added directly to a Designer file in XAML format, but our preferred method is to add them all in one dedicated file and use the aforementioned ActivityIconConverter to pull them into each activity. In this way, the main Designer file remains uncluttered by often long icon code.

Icons.xaml

Within your Design project, navigate to Themes > Icons.xaml.



You'll notice that within this file are two blocks of code that hold the icons for the Parent Scope and the Child Activity and which are labeled as such. The content of each icon will obviously vary, but what must remain constant is the x:Key attribute, which takes the form <Activity Name>Icon. The Child Activity's icon code, for example, has the following format:
<DrawingBrush x:Key="ChildActivityIcon" Viewbox="0,0,52.706,14.497" ViewboxUnits="Absolute" Stretch="Uniform">
...        
</DrawingBrush><DrawingBrush x:Key="ChildActivityIcon" Viewbox="0,0,52.706,14.497" ViewboxUnits="Absolute" Stretch="Uniform">
...        
</DrawingBrush>

Designer File

Navigate back to your designer file, ChildActivityDesigner.xaml. The following block of code is responsible for adding an icon to the designer and is constant across all activities in the package. It functions by searching Icons.xaml for a key with the same name as the activity itself and adds that XAML code to the current file. Notice that the ConverterParameter references your Designer project by name.
<a href="sap:ActivityDesigner.Icon">sap:ActivityDesigner.Icon</a>
    <DrawingBrush Stretch="Uniform" Drawing="{Binding Path=ModelItem, Converter={StaticResource ActivityIconConverter}, ConverterParameter=pack://application:\)\),\)\),\)\),/MyCompany.MyProduct.Activities.Design;component/themes/icons.xaml}" />
</sap:ActivityDesigner.Icon><a href="sap:ActivityDesigner.Icon">sap:ActivityDesigner.Icon</a>
    <DrawingBrush Stretch="Uniform" Drawing="{Binding Path=ModelItem, Converter={StaticResource ActivityIconConverter}, ConverterParameter=pack://application:\)\),\)\),\)\),/MyCompany.MyProduct.Activities.Design;component/themes/icons.xaml}" />
</sap:ActivityDesigner.Icon>

Adding components

You now have the foundation of a designer, but it's still completely blank! Let's expand upon this by adding two textfields, one for each of the Child Activity's inputs.

Activity Decorator

Start by giving the activity a UiPath look and feel. This can be easily done by adding an ActivityDecoratorControl to your designer immediately below your icon code. Visual Studio may prompt you to import the UiPath.Shared.Activities.Design.Controls namespace, but if not, add this to the class definition at the top of the file as well.
<sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             ...
             xmlns:controls="clr-namespace:UiPath.Shared.Activities.Design.Controls">
<?comment-start?>
Resources
<?comment-end?>
<?comment-start?>
Icons
<?comment-end?>
    <controls:ActivityDecoratorControl Style="{StaticResource ActivityDecoratorStyle}">
        
    </controls:ActivityDecoratorControl>
</sap:ActivityDesigner><sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             ...
             xmlns:controls="clr-namespace:UiPath.Shared.Activities.Design.Controls">
<?comment-start?>
Resources
<?comment-end?>
<?comment-start?>
Icons
<?comment-end?>
    <controls:ActivityDecoratorControl Style="{StaticResource ActivityDecoratorStyle}">
        
    </controls:ActivityDecoratorControl>
</sap:ActivityDesigner>
All a designers components should be wrapped in an ActivityDecoratorControl, which provides standard activity behaviors such as the ability to minimize a large designer and display the message "Double click to view." in its place. Details like this are small but combine to give a UiPath feel to the overall activity package.

Rebuild your package and you'll see that it now looks slightly different:



Grid Layout

Next, let's set the layout of the activity so it can display labels and text fields in an appealing way. WPF has 6 main layouts, but we're going to use a Grid panel to hold our controls. The Grid works by first defining a number of rows and columns along with their heights and widths respectively. Start by defining 2 rows and 2 columns.

<controls:ActivityDecoratorControl Style="{StaticResource ActivityDecoratorStyle}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
      
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
    </Grid>
</controls:ActivityDecoratorControl><controls:ActivityDecoratorControl Style="{StaticResource ActivityDecoratorStyle}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
      
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
    </Grid>
</controls:ActivityDecoratorControl>
Notice that the heights and widths do not contain actual values, but instead use wildcard characters (*). You are free to specify exact numerical values, but this notation allows each cell to size dynamically in relation to those around it. The RowDefinition heights are both * so they will consume as much vertical space as exists. The ColumnDefinition widths, however, are * and 3*, meaning the first column will consume 25% of any available whitespace along the width and the second column 75%.

Add a Textbox

Now that the layout is set, we'll add two textboxes with which the user can access the Child Activity's two input properties--First Number and Second Number. Start by adding a Label after the Grid definitions for the First Number.

There are 3 properties set to this Label:
  • Grid.Row: Positions the label in the first row of the Grid defined above.
  • Grid.Column: Positions the label in the first column of the Grid defined above.
  • Content: Sets the text that appears in the label.

See here for a complete list of properties available to WPF elements.

<Grid>
<?comment-start?>
Grid definitions
<?comment-end?>
    <Label Grid.Row="0" Grid.Column="0" 
           Content="First Number" />
</Grid><Grid>
<?comment-start?>
Grid definitions
<?comment-end?>
    <Label Grid.Row="0" Grid.Column="0" 
           Content="First Number" />
</Grid>

Next, let's add an ExpressionTextBox to allow for user input. If Visual Studio does not prompt you to do so, you must manually add two more namespaces to the class definition.

xmlns:view="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
xmlns:system="clr-namespace:System;assembly=mscorlib"xmlns:view="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
xmlns:system="clr-namespace:System;assembly=mscorlib"
There are 4 properties set on this ExpressionTextBox:
  • Grid.Row: Positions the label in the first row of the Grid defined above.
  • Grid.Column: Positions the label in the second column of the Grid defined above.
  • HintText: Sets the tooltip text that appears within the textbox when empty and also when the user's mouse hovers over this field.
  • ExpressionType: Sets the type of data that is allowed in this field. Since our property is a number of type int, this is set to Int32.
    <Grid>
    <?comment-start?>
    Grid definitions
    <?comment-end?>
        <Label Grid.Row="0" Grid.Column="0" 
               Content="First Number" />
        <view:ExpressionTextBox Grid.Row="0" Grid.Column="1" 
                                HintText="The first addend"
                                ExpressionType="system:Int32" />
    </Grid><Grid>
    <?comment-start?>
    Grid definitions
    <?comment-end?>
        <Label Grid.Row="0" Grid.Column="0" 
               Content="First Number" />
        <view:ExpressionTextBox Grid.Row="0" Grid.Column="1" 
                                HintText="The first addend"
                                ExpressionType="system:Int32" />
    </Grid>

Rebuild your package and it should now look like this:



Add another Label and ExpressionTextBox for the Second Number property, remembering that these controls will now be in Grid.Row="1". The final result should look like this:


Bind Designer to Activity

Try to click either of your textboxes and you'l find that they are non-responsive. This is because the ExpressionTextBox works differently than a normal Textbox. Where Textboxes support String inputs, ExpressionTextBoxes allow the user to enter complex VB.Net expressions (e.g. Int32.MaxValue, 2+2, SomeUiPathVariable) and can bind this value to a property in your activity.
In order to bind your designer fields to your activity properties, add 2 more properties to each ExpressionTextBox:
  • OwnerActivity: Specifies a ViewModel used by the designer to link to the activity file. For our purposes, this will always be ModelItem.
  • Expression: Supplies the activity property to which this field will be bound. There are 4 main components here:
  • Binding: Specifies by name the activity property to which to bind. If the ModelItem holds your activity's contents, ModelItem.FirstNumber links directly to the First Number property.
  • Converter: Provides a class to convert between objects of different types. In our case, the designer field holds an int, but the activity property is of type InArgument<int>, so we add a standard ArgumentToExpressionConverter to handle the binding between them.
  • ConverterParameter: Specifies the type of argument to which this field is bound. In this case, we are binding to InArgument<> properties, so the ConverterParameter is In, but InOut and Out are options as well.
  • Mode: Indicates whether changes in the designer field will trigger updates or the activity property and vice versa. Set this as TwoWay to allow the user to update either the designer or the properties pane. See here for all other options.
Import the ArgumentToExpressionConverter by adding the following line to your ResourceDictionary and importing the clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation namespace in your class definition.
<converters1:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" /><converters1:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />

All together, your Child Activity designer and code should appear as below. Enter values into each field and notice how the corresponding properties update.



<sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             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:converters="clr-namespace:UiPath.Shared.Activities.Design.Converters"
             xmlns:converters1="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"
             xmlns:controls="clr-namespace:UiPath.Shared.Activities.Design.Controls"
             xmlns:view="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
             xmlns:system="clr-namespace:System;assembly=mscorlib">
    <a href="sap:ActivityDesigner.Resources">sap:ActivityDesigner.Resources</a>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="..\)\)Themes\)\)Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <converters1:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />
            <converters:ActivityIconConverter x:Key="ActivityIconConverter" />
        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    <a href="sap:ActivityDesigner.Icon">sap:ActivityDesigner.Icon</a>
        <DrawingBrush Stretch="Uniform" Drawing="{Binding Path=ModelItem, Converter={StaticResource ActivityIconConverter}, ConverterParameter=pack://application:\)\),\)\),\)\),/MyCompany.MyProduct.Activities.Design;component/themes/icons.xaml}" />
    </sap:ActivityDesigner.Icon>
    <controls:ActivityDecoratorControl Style="{StaticResource ActivityDecoratorStyle}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="3*"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Row="0" Grid.Column="0" 
                   Content="First Number" />
            <view:ExpressionTextBox Grid.Row="0"  Grid.Column="1" 
                                    OwnerActivity="{Binding Path=ModelItem}" 
                                    ExpressionType="system:Int32" 
                                    HintText="The first addend" 
                                    Expression="{Binding Path=ModelItem.FirstNumber,Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In, Mode=TwoWay}" />
            <Label Grid.Row="1" Grid.Column="0" 
                   Content="Second Number" />
            <view:ExpressionTextBox Grid.Row="1"  Grid.Column="1" 
                                    OwnerActivity="{Binding Path=ModelItem}" 
                                    ExpressionType="system:Int32" 
                                    HintText="The second addend" 
                                    Expression="{Binding Path=ModelItem.SecondNumber,Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In, Mode=TwoWay}" />
        </Grid>
    </controls:ActivityDecoratorControl>
</sap:ActivityDesigner><sap:ActivityDesigner x:Class="MyCompany.MyProduct.Activities.Design.ChildActivityDesigner"
             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:converters="clr-namespace:UiPath.Shared.Activities.Design.Converters"
             xmlns:converters1="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"
             xmlns:controls="clr-namespace:UiPath.Shared.Activities.Design.Controls"
             xmlns:view="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
             xmlns:system="clr-namespace:System;assembly=mscorlib">
    <a href="sap:ActivityDesigner.Resources">sap:ActivityDesigner.Resources</a>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="..\)\)Themes\)\)Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <converters1:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />
            <converters:ActivityIconConverter x:Key="ActivityIconConverter" />
        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    <a href="sap:ActivityDesigner.Icon">sap:ActivityDesigner.Icon</a>
        <DrawingBrush Stretch="Uniform" Drawing="{Binding Path=ModelItem, Converter={StaticResource ActivityIconConverter}, ConverterParameter=pack://application:\)\),\)\),\)\),/MyCompany.MyProduct.Activities.Design;component/themes/icons.xaml}" />
    </sap:ActivityDesigner.Icon>
    <controls:ActivityDecoratorControl Style="{StaticResource ActivityDecoratorStyle}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="3*"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Row="0" Grid.Column="0" 
                   Content="First Number" />
            <view:ExpressionTextBox Grid.Row="0"  Grid.Column="1" 
                                    OwnerActivity="{Binding Path=ModelItem}" 
                                    ExpressionType="system:Int32" 
                                    HintText="The first addend" 
                                    Expression="{Binding Path=ModelItem.FirstNumber,Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In, Mode=TwoWay}" />
            <Label Grid.Row="1" Grid.Column="0" 
                   Content="Second Number" />
            <view:ExpressionTextBox Grid.Row="1"  Grid.Column="1" 
                                    OwnerActivity="{Binding Path=ModelItem}" 
                                    ExpressionType="system:Int32" 
                                    HintText="The second addend" 
                                    Expression="{Binding Path=ModelItem.SecondNumber,Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In, Mode=TwoWay}" />
        </Grid>
    </controls:ActivityDecoratorControl>
</sap:ActivityDesigner>
  • Class Definition
  • Resources
  • Icons
  • Icons.xaml
  • Designer File
  • Activity Decorator
  • Grid Layout
  • Add a Textbox
  • Bind Designer to Activity

Was this page helpful?

Get The Help You Need
Learning RPA - Automation Courses
UiPath Community Forum
Uipath Logo White
Trust and Security
© 2005-2024 UiPath. All rights reserved.