C# Dynamo Nodes - Dropdown input Node

dynamo

#1

Hi, my second main issue is creating drop down Node.
Currently, I am using separate nodes for each simple piece of data. Would be amazing to combine them together into one DropDown Node. So far no success at all.

/// </summary>  
public enum TSDZoneArray
{
    /// <summary>Dry Bulb Temperature</summary>
    DryBulbTemp = 1,
    /// <summary>MR Temperature</summary>
    MRTemp = 2,
    /// <summary>Resultant Temperature</summary>
    ResultantTemp = 3,
    /// <summary>Sensible Load</summary>
    SensibleLoad = 4,
    /// <summary>Heating Load</summary>
    HeatingLoad = 5,
    /// <summary>Cooling Load</summary>
    CoolingLoad = 6,
    /// <summary>Solar Gain</summary>
    SolarGain = 7,
    /// <summary>Lighting Gain</summary>
    LightingGain = 8,
    /// <summary>Inf Vent Gain</summary>
    InfVentGain = 9,
    /// <summary>Air Movement Gain</summary>
    AirMovementGain = 10,

}


DropDown C#
C# Dropdown
#2

You need to use WPF and before you ask, the method of creating interfaces on nodes is quite ugly and a far cry from a few lines of code unfortunately. If you install the Dynamo nuget package in visual studio for WPF it will install all of the required libraries. The rest, I leave to you :wink:


#3

Some helpful resources. (Disclaimer: I do not know how to make nodes like this yet, still learning.)


#4

I will actually argue to the contrary. It’s not that bad. I usually use Grasshopper for the comparison, and in this particular case the Dynamo methods for defining dropdowns are pretty decent. Here’s one of them adopted from Max’s recent contributions to DynamoRevit repo:

[NodeName("Select Rule Type")]
    [NodeCategory("Revit.Filter.RuleType")]
    [NodeDescription("FilterTypeSelectorDescription", typeof(DSRevitNodesUI.Properties.Resources))]
    [IsDesignScriptCompatible]
    public class RuleTypes : CustomGenericEnumerationDropDown
    {
        public RuleTypes() : base("RuleType", typeof(Revit.Filter.FilterRule.RuleType)) { }
    }

This inherits from this class:

    /// <summary>
    /// Generic UI Dropdown node baseclass for Enumerations.
    /// This class populates a dropdown with all enumeration values of the specified type.
    /// </summary>
    public abstract class CustomGenericEnumerationDropDown : RevitDropDownBase
    {
        /// <summary>
        /// Generic Enumeration Dropdown
        /// </summary>
        /// <param name="name">Node Name</param>
        /// <param name="enumerationType">Type of Enumeration to Display</param>
        public CustomGenericEnumerationDropDown(string name, Type enumerationType) : base(name) { this.EnumerationType = enumerationType; PopulateDropDownItems(); }

        /// <summary>
        /// Type of Enumeration
        /// </summary>
        private Type EnumerationType
        {
            get;
            set;
        }

        protected override CoreNodeModels.DSDropDownBase.SelectionState PopulateItemsCore(string currentSelection)
        {
            PopulateDropDownItems();
            return SelectionState.Done;
        }

        /// <summary>
        /// Populate Items in Dropdown menu
        /// </summary>
        public void PopulateDropDownItems()
        {
            if (this.EnumerationType != null)
            {
                // Clear the dropdown list
                Items.Clear();

                // Get all enumeration names and add them to the dropdown menu
                foreach (string name in Enum.GetNames(EnumerationType))
                {
                    Items.Add(new CoreNodeModels.DynamoDropDownItem(name, Enum.Parse(EnumerationType, name)));
                }

                Items = Items.OrderBy(x => x.Name).ToObservableCollection();
            }
        }

        /// <summary>
        /// Assign the selected Enumeration value to the output
        /// </summary>
        public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
        {
            // If the dropdown is still empty try to populate it again          
            if (Items.Count == 0 || Items.Count == -1)
            {
                if (this.EnumerationType != null && Enum.GetNames(this.EnumerationType).Length > 0)
                {
                    PopulateItems();
                }
            }

            // get the selected items name
            var stringNode = AstFactory.BuildStringNode((string)Items[SelectedIndex].Name);

            // assign the selected name to an actual enumeration value
            var assign = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), stringNode);

            // return the enumeration value
            return new List<AssociativeNode> { assign };
        }
    }

If you have pasted the CustomGenericEnumerationDropDown into your code, then you can use that first method to define dropdowns by simply inheriting from it.

Cheers!

PS. @Thomas_Mahon it is correct that you can go all out custom WPF dropdown, and use a NodeModel route, but then yes, one would need to create all of the interaction logic, handle events, etc. It does get a little more cumbersome then. For this application its not necessary.


Custom Drop-down/Combobox input node on Dynamo Player UI?
#5

2 posts were split to a new topic: C# Dropdown