You don't need a HtmlHelper, what you actually need is just a way to convert from your DropdownTreeview object-graph to an IEnumerable<SelectListItem> that you can pass into the existing DropDownFor HtmlHelper as well as the (arguably superior) SelectTagHelper (aka <select asp-items>).
Because your class DropdownTreeview items do not contain any object-references to parent class DropdownTreeview items (instead you're using long? IdParent) you can't use existing straightforward methods for traversing the graph. In my approach I convert these to a traversible object-graph which can then be flattened to a list of SelectListItem objects.
I'm going to rename your class DropdownTreeview to class TreeNode because each instance represents a node, not the entire tree.
You can directly copy and paste this into Linqpad to see it run (you'll need to add a NuGet reference to ASP.NET Core to use SelectListItem, of course):
void Main()
{
TreeNode[] initialNodes = new[]
{
new TreeNode( 1, null, "Computers" ),
new TreeNode( 2, 1, "Desktops" ),
new TreeNode( 3, 1, "Notebooks" ),
new TreeNode( 4, 1, "Software" ),
new TreeNode( 5, null, "Electronics" ),
new TreeNode( 6, 5, "Camera photo" ),
new TreeNode( 7, 5, "Cell phones" ),
new TreeNode( 8, 5, "Others" ),
new TreeNode( 9, null, "Apparel" ),
new TreeNode( 10, 9, "Shoes" ),
new TreeNode( 11, 9, "Clothing" ),
new TreeNode( 12, 11, "Shirt" ),
new TreeNode( 13, 11, "TShirt" ),
new TreeNode( 14, 9, "Accessories" ),
new TreeNode( 15, null, "Downloads" ),
new TreeNode( 16, null, "Books" ),
new TreeNode( 17, null, "Jewelry" ),
new TreeNode( 18, null, "Gift Cards" )
};
TreeGraph graph = new TreeGraph( initialNodes );
// graph.EnumerateDepthFirst().Dump();
graph.AsSelectListItems().Dump();
}
public record TreeNode( Int64 id, Int64? parentId, String name );
public class TreeGraph
{
private readonly IReadOnlyDictionary<Int64,( TreeNode node, List<TreeNode> children )> nodesById;
public TreeGraph( IEnumerable<TreeNode> initialNodes )
{
Dictionary<Int64,( TreeNode node, List<TreeNode> children )> nodesByIdMut = initialNodes
.ToDictionary( n => n.id, n => ( node: n, children: new List<TreeNode>() ) );
foreach( TreeNode child in initialNodes.Where( n => n.parentId.HasValue ) )
{
nodesByIdMut[ child.parentId!.Value ].children.Add( child );
}
this.nodesById = nodesByIdMut;
}
private String GetPath( TreeNode node )
{
if( node.parentId == null ) return node.name;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode? n = node;
while( n != null )
{
stack.Push( n );
n = n.parentId.HasValue ? ( nodesById[ n.parentId.Value ].node ) : null;
}
return String.Join( separator: " > ", stack.Select( n2 => n2.name ) );
}
private IEnumerable<TreeNode> GetRoots()
{
return this.nodesById.Values
.Where( t => t.node.parentId == null )
.OrderBy( t => t.node.name )
.Select( t => t.node );
}
private IEnumerable<TreeNode> GetChildren( TreeNode node )
{
return this.nodesById[ node.id ].children;
}
public IEnumerable<( TreeNode n, String path )> EnumerateDepthFirst()
{
foreach( TreeNode root in this.GetRoots() )
{
foreach( ( TreeNode descendant, String path ) pair in this.EnumerateDepthFirstFrom( root ) )
{
yield return pair;
}
}
}
private IEnumerable<( TreeNode n, String path )> EnumerateDepthFirstFrom( TreeNode root )
{
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.Push( root );
while( stack.Count > 0 )
{
TreeNode n = stack.Pop();
foreach( TreeNode c in this.GetChildren( n ) )
{
stack.Push( c );
}
String path = this.GetPath( n );
yield return ( n, path );
}
}
public IEnumerable<SelectListItem> AsSelectListItems()
{
return this.EnumerateDepthFirst()
.Select( pair => new SelectListItem()
{
Text = pair.path,
Value = pair.n.id.ToString( CultureInfo.InvariantCulture )
} )
}
}
Screenshot proof:

To then use this in your Razor (.cshtml) views, instantiate the TreeGraph somewhere and pass the result of AsSelectListItems() into asp-items, like so:
@model MyPageViewModel
TreeNode[] nodes = this.Model.TreeNodes;
TreeGraph graph = new TreeGraph( nodes );
//
<form>
<select asp-items="@( graph.AsSelectListItems() )"></select>
</form>
<select>for your efforts.<select>element only supports up-to 2 levels of nesting via<optgroup>.