Struggling to build custom activities with drag-and-drop support (like Excel Scope / If)

Hey everyone,

I’ve been trying to teach myself custom activity development in UiPath — mainly how to build the UI and wire up the internal logic, and eventually get to a point where I can recreate functionality like Excel Application Scope or If, where you can drag and drop other activities inside them.

I’ve watched a bunch of YouTube tutorials and gone through the official docs, but honestly I’m more confused now than when I started, because the two seem to teach completely different approaches and neither really explains the “why” behind it.

A couple of things I’m stuck on:

->1. Attributes vs ViewModel — am I missing something?

The tutorials I followed use simple attributes on the properties, like:

[Category("Input")]
[DisplayName("Timeout (ms)")]
[Description("Specifies the amount of time (in milliseconds) to wait before throwing a timeout exception. Default is 30,000 ms.")]
[DefaultValue(30000)]

And I’ve actually built a few activities this way that work fine. But then I looked at the official docs and they’re doing something totally different, using a ViewModel setup like:

// Principal (main) properties
To.DisplayName = Resources.EmailSender_To_DisplayName;
To.Tooltip = Resources.EmailSender_To_Tooltip;
To.IsRequired = true;
To.IsPrincipal = true;
To.OrderIndex = order++;

Since I can get things working with just attributes, why would I need the ViewModel approach at all? Is there a point where attributes stop being enough, or is this more of a “best practice vs quick and dirty” thing?

–>2. The actual thing I really need help with — drag and drop containers

This is my main blocker. I want to build something like Excel Application Scope, where you can drop other activities inside it and they run within that scope. I have no idea where to even start with this — what base class do I need, how do I expose a spot for child activities, and how does the designer know to show that dashed “drop activities here” box?

also the view is very much fine for simple activites which have 8-9 or may be more input/output arguments, when when i try to hide or show something using check box , the view flattens and all the I/O arguments are visible only on Properties Panel not on Canvas.

If anyone’s built something like this before, or knows a tutorial/example that actually goes into this (not just the basic “hello world” custom activity stuff), I’d really appreciate it. Most resources I’ve found stop right at the point where things get interesting.

Thanks in advance!

I can help here.

  1. Viewmodel is the up to date way to do it, the other stuff you see is legacy and wont be supported on new versions, the ViewModel is .NETCore stuff and is in the latest. Its confusing with all the tutorials around, 100% agreed, I got mixed up by that in the past.

This topic is helpful if you havent seen it

  1. I agree, there is no good tutorial on this and it took me a while to figure this out myself, its been on my ToDo list for quite a while to close this gap and write a tutorial, but I havent had the time.

Here is some TLDR key info.

You need to add a property to the ViewModel, this tells the designer, which dynamically builds the application card, what to render, you use it for things like DesignInArgument or DesignOutArgument, but it also has this property for rendering a child object container.

public DesignProperty<ActivityAction<object>> Body { get; set; }

In the other part, the activity code, that needs to inherit the following, cause the nature of any scope activity must be async, this is instead of inheriting CodeActivity

AsyncTaskNativeActivity

You need to add this property to store the child activities inside the scope.

//Needed for the child activities
[Browsable(false)]
public ActivityAction<object> Body { get; set; }

I have this in my constructor, which I think is needed, to set some default values.

Body = new ActivityAction<object>
{
    Argument = new DelegateInArgument<Object>("ParentContainerTag"),
    Handler = new Sequence { DisplayName = "Do" }
};

Under the old inheritance you would have this, but its no longer valid

protected override void Execute(CodeActivityContext context)

Instead you want the following, to again make it asynchronous.

protected override async Task<Action<NativeActivityContext>> ExecuteAsync(NativeActivityContext context, CancellationToken cancellationToken)

At the end you must schedule the child activities to run with the following code.

// Schedule child activities
return (ctx) =>
{
    // Schedule child activities
    if (Body != null)
        ctx.ScheduleAction<Object>(Body, null, OnCompleted, OnFaulted);
};

The schedulaction thing has some delegates to other functions, specifically OnCompleted and OnFaulted.

You can implement with this kind of pattern, do any sort of cleanup you require via them.

private void OnCompleted(NativeActivityContext context, ActivityInstance completedInstance)

This should give you some direction, but message again if you get stuck.

`Hi , thanks for the reply , and also i tried the same thing initially but not able to get the ui on the screen , but sure i will try it and will ping you again if i stuck somewhere, and you said that this is legacy(the attribute stuff) but it is still working on my new studio which is 26.x.x. from which version, it will not be supported?

Sure, from what I understand (I stand to be corrected here but think I am right) is that the attribute style is using the .NET Framework, which is no longer being worked on or getting updates etc etc.
Everything has now moved to .NET Core, which is what the way I showed you is built on.

The way to think of it, is that you could make a Windows - Legacy project in UiPath for several years right? But did it make sense to do that when you could see it was going to be legacy and the 64 bit version was available to use and would have longer term support.

The same is true here, you CAN still make a version using the .NET Framework in the older way, which is in some ways simpler on face value, especially since there are far more tutorials, but you won’t get the same lifespan as the .NET Core version and you’ll most likely be forced to migrate at some point anyway.

I can’t tell you what version it might no longer be supported on regarding Studio, so its your call. Its not wrong to do it in the older framework, so I’m not saying you shouldn’t. If you are really blocked on the .NET Core version and just need it done then its not a terrible idea, just make an informed choice.