C# Dropdown


#1

I’m trying to make this code work, but I cannot find this RevitDropDownBase class, that has to be inherited from. Where is this class from or what reference do I have to add to get access to it?

I tried searching on the this forum, also on the Dynamo repository on github, but there’s not a single hit anywhere but this thread.


C# Dynamo Nodes - Dropdown input Node
#2

After digging a bit deeper I found that all those classes inherit from the DSDropDownBase class, but I still cannot make this work correctly.

If the constructur is commented out (I found this by accident) I can almost get the GUI working with the options shown in the dropdown, however the node throws an error. If the constructor is in the code, the node does not show up in Dynamo at all. Does anyone have a clue what I’m doing wrong there?

public class DummyDropdown : DSDropDownBase
{
    //Only if comment this line out, does the node show up in Dynamo but does not work.
    protected DummyDropdown() : base("Selection") { }

    protected override SelectionState PopulateItemsCore(string currentSelection)
    {
        Items.Clear();
        Dictionary<string, int> dropdownItems = new Dictionary<string, int> {
            { "Test1", 1 },
            { "Test2", 2 },
            { "Test3", 3 },
            { "Test4", 4 },
        };
        foreach (KeyValuePair<string, int> item in dropdownItems)
        {
            Items.Add(new DynamoDropDownItem(item.Key, item.Value));
        }
        return SelectionState.Restore;
    }

    public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
    {
        return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildIntNode((int)(Items[SelectedIndex].Item))) };
    }
}

#3

you can’t import UI nodes via zero touch (as far as I know) - these are nodes which inherit directly from NodeModel and need to be imported as part of a package or from the dynamo nodes folder.

I think there was just a discussion where @Konrad_K_Sobon showed how to do this with a revit class pretty simply.


#4

Yeah, it was answered here: C# Dynamo Nodes - Dropdown input Node


#5

Yes, I initially replied to the same thread you are reffering to and asked for a bit more help, but an admin split my replies into this thread.

I think it makes sense to inherit from the more generic DSDropDownBase, because I’m trying to get some very specific behaviour (only show Revit Model Groups that have a name matching a RegEx and update if something changes about the groups content). I’m quite sure I can figure out the rest, if I get this dropdown working.


#6

I figured it out now. It is important that the BuildOutputAst is able to return a null node, in case the SelectedIndex is -1. Also had to make constructor public (Can’t understand how I missed it earlier :smiley: ). This is the code that works:

public class DummyDropdown : DSDropDownBase
{
    public DummyDropdown() : base("Name of the output") { }

    protected override SelectionState PopulateItemsCore(string currentSelection)
    {
        Items.Clear();
        Dictionary<string, int> dropdownItems = new Dictionary<string, int> {
            { "Test1", 1 },
            { "Test2", 2 },
            { "Test3", 3 },
            { "Test4", 4 },
        };
        foreach (KeyValuePair<string, int> item in dropdownItems)
        {
            Items.Add(new DynamoDropDownItem(item.Key, item.Value));
        }
        return SelectionState.Restore;
    }

    public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes )
    {
        if (Items.Count == 0 ||
            SelectedIndex == -1) //NB! This line is crucial for some reason
        {
            return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };
        }

        var intNode = AstFactory.BuildIntNode((int)Items[SelectedIndex].Item);
        var assign = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), intNode);
        return new List<AssociativeNode> { assign };
    }
}