Problem with DropDown

When I add the DSRevitNodesUI library, the same error occurs, currently I am working on Revit 2020
image


The ‘+’ character, hexadecimal value 0x2B, cannot be included in a name.

at System.Xml.XmlDocument.CheckName(String name)
at System.Xml.XmlElement…ctor(XmlName name, Boolean empty, XmlDocument doc)
at System.Xml.XmlDocument.CreateElement(String prefix, String localName, String namespaceURI)
at System.Xml.XmlDocument.CreateElement(String name)
at Dynamo.Graph.ModelBase.CreateElement(XmlDocument xmlDocument, SaveContext context)
at Dynamo.Core.UndoRedoRecorder.RecordActionInternal(XmlElement group, ModelBase model, UserAction action)
at Dynamo.Core.UndoRedoRecorder.ModelModificationUndoHelper…ctor(UndoRedoRecorder recorder, IEnumerable1 models) at Dynamo.Graph.Workspaces.WorkspaceModel.UpdateModelValue(IEnumerable1 modelGuids, String propertyName, String value)
at Dynamo.Models.DynamoModel.UpdateModelValueImpl(UpdateModelValueCommand command)
at Dynamo.Models.DynamoModel.ExecuteCommand(RecordableCommand command)
at Dynamo.ViewModels.NodeViewModel.set_PreviewPinned(Boolean value)
at Dynamo.UI.Controls.PreviewControl.OnMapPinMouseClick(Object sender, MouseButtonEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

can show the code as well?? cause i cant reproduce the same error from my side

DuctTypeModel.txt (2.6 KB)
Here’s the code in my class.

[NodeName("DuctTypes")]
[NodeCategory("DynaMEP.DynaMEP.MEP.Ducts")]
[NodeDescription("Get All Duct Type From Model Dropdown")]
[IsDesignScriptCompatible]
public class DuctTypeModel : RevitDropDownBase
{
    const string NoDuctTypes = "No Duct Types Found.";

    public DuctTypeModel() : base("DuctType")
    {

    }

    [Newtonsoft.Json.JsonConstructor]
    public DuctTypeModel(IEnumerable<PortModel> inports, IEnumerable<PortModel> outports) : base("DuctType", inports, outports)
    {

    }

    protected override SelectionState PopulateItemsCore(string currentSelection)
    {
        Dictionary<string, int> dropdownitems = new Dictionary<string, int>();
        using (Document doc = DocumentManager.Instance.CurrentDBDocument)
        using (FilteredElementCollector col = new FilteredElementCollector(doc).OfClass(typeof(DuctType)))
        {
            foreach (Autodesk.Revit.DB.Element ele in col)
                dropdownitems.Add(ele.Name, ele.Id.IntegerValue);
        }

        if (dropdownitems.Count == 0)
        {
            Items.Add(new DynamoDropDownItem(NoDuctTypes, null));
            SelectedIndex = 0;
            return SelectionState.Done;
        }
        Items.Clear();
        Items = dropdownitems.Select(x => new DynamoDropDownItem(x.Key, x.Value)).OrderBy(x => x.Name).ToObservableCollection();
        return SelectionState.Restore;
    }

    public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
    {
        if (Items.Count == 0 || SelectedIndex == -1 || Items[0].Name == NoDuctTypes)
        {
            return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };
        }

        Func<int, bool, Revit.Elements.Element> callfunction = new Func<int, bool, Revit.Elements.Element>(ElementSelector.ByElementId);
        AssociativeNode selectId = AstFactory.BuildIntNode((int)Items[SelectedIndex].Item);
        AssociativeNode isRevitOwned = AstFactory.BuildBooleanNode(false);

        AssociativeNode callFunctionNode = AstFactory.BuildFunctionCall(
            callfunction,
            new List<AssociativeNode>
            {
                selectId,isRevitOwned
            });

        BinaryExpressionNode assign1 = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), callFunctionNode);

        return new[]
        {
            assign1
        };
    }
}

this should do the trick. and you didnt even make changes to the one i told you about…

I work with your new code, it shows the node name but I do not click to display that node to the main screen.

i honestly have no idea to help you with that, the error is new to me too.


the underlined error is the error that is causing the node to not appear.

1 Like

I thank you so much for help, I will continue to look for solutions to this error. I hope someone will find the solution.

[NodeName("Wall Types")]
[NodeCategory(BuiltinNodeCategories.REVIT_SELECTION)]
[NodeDescription("WallTypesDescription", typeof(Properties.Resources))]
[IsDesignScriptCompatible]
public class WallTypes : RevitDropDownBase
{
    private const string outputName = "Wall Type";

    public WallTypes() : base(outputName) { }

    [JsonConstructor]
    public WallTypes(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(outputName, inPorts, outPorts) { }

    protected override SelectionState PopulateItemsCore(string currentSelection)
    {
        Items.Clear();

        var fec = new FilteredElementCollector(DocumentManager.Instance.CurrentDBDocument);

        fec.OfClass(typeof(Autodesk.Revit.DB.WallType));
        var elements = fec.ToElements();
        if (!elements.Any())
        {
            Items.Add(new DynamoDropDownItem(Properties.Resources.NoWallTypesAvailable, null));
            SelectedIndex = 0;
            return SelectionState.Done;
        }

        Items = elements.Select(x => new DynamoDropDownItem(x.Name, x)).OrderBy(x => x.Name).ToObservableCollection();
        return SelectionState.Restore;
    }

    public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
    {
        if(!CanBuildOutputAst(Properties.Resources.NoWallTypesAvailable))
            return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };
        
        var args = new List<AssociativeNode>
        {
            AstFactory.BuildStringNode(((Autodesk.Revit.DB.WallType) Items[SelectedIndex].Item).Name)
        };
        var functionCall = AstFactory.BuildFunctionCall("Revit.Elements.WallType",
                                                        "ByName",
                                                        args);

        return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), functionCall) };
    }
}

If you look at DynamoRevit Souce code, what they provided is similar to what i had done for you. So honestly, i have no idea whats wrong too?

I found a problem like me here but I do not see what is the solution.I Hope @Konrad_K_Sobon Can help me ! https://github.com/DynamoDS/Dynamo/issues/5120

okay i have found out my mistake… It was the dictionary issue…
heres the code:

[NodeName("Duct Types")]
[NodeDescription("Get All Duct Type From Model Dropdown")]
[NodeCategory("DynaMEP.MEP.Ducts")]
[IsDesignScriptCompatible]
public class DuctTypes : RevitDropDownBase
{
    private const string outPutName = "Duct Type";
    private const string NO_DUCT_TYPES = "No Duct Types Found.";

    public DuctTypes() : base(outPutName) { }

    [JsonConstructor]
    public DuctTypes(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(outPutName, inPorts, outPorts) { }

    protected override SelectionState PopulateItemsCore(string currentSelection)
    {
        Items.Clear();

        Dictionary<int, string> eleNameInt = new Dictionary<int, string>();
        
        using (FilteredElementCollector col = new FilteredElementCollector(DocumentManager.Instance.CurrentDBDocument).OfClass(typeof(DuctType)))
        {
            var eles = col.ToElements();
            if (!eles.Any())
            {
                Items.Add(new DynamoDropDownItem(NO_DUCT_TYPES, null));
                SelectedIndex = 0;
                return SelectionState.Done;
            }
            foreach (var ele in eles)
                eleNameInt.Add(ele.Id.IntegerValue,  ele.Name);
        }

        Items = eleNameInt.Select(x => new DynamoDropDownItem(x.Value, x.Key)).OrderBy(x => x.Name).ToObservableCollection();
        return SelectionState.Restore;
    }

    public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
    {
        if (!CanBuildOutputAst(NO_DUCT_TYPES))
            return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };

        List<AssociativeNode> args = new List<AssociativeNode>()
        {
            AstFactory.BuildIntNode((int)Items[SelectedIndex].Item),
            AstFactory.BuildBooleanNode(true),
        };

        Func<System.Int32, System.Boolean, Revit.Elements.Element> func = new Func<System.Int32, System.Boolean, Revit.Elements.Element>(Revit.Elements.ElementSelector.ByElementId);

        AssociativeNode callFunctionNode = AstFactory.BuildFunctionCall<System.Int32, System.Boolean, Revit.Elements.Element>(
            Revit.Elements.ElementSelector.ByElementId,
            args
            );

        BinaryExpressionNode assign1 = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), callFunctionNode);

        return new[]
        {
            assign1
        };

        bool CanBuildOutputAst(string itemValueToIgnore = null, string selectedValueToIgnore = null)
        {
            if (Items.Count == 0 || SelectedIndex < 0)
                return false;
            if (!string.IsNullOrEmpty(itemValueToIgnore) && Items[0].Name == itemValueToIgnore)
                return false;
            if (!string.IsNullOrEmpty(selectedValueToIgnore) && Items[SelectedIndex].Name == selectedValueToIgnore)
                return false;
            return true;
        }
    }
}


I tried with your new code but the error is still happening
image

what is the namespace you are using?? Mostly is that you have accidentally concat strings together and formed an illegal character “+” somewhere along the line.

Im using with name

DynaMEPUI.Duct

Have Problem ?

for explicit node, dont think there is a need for having “.” in your namepsace, unless you have a really huge class? Possible to show me the entire class? does this error only happens at that node?

Im only use a class for one problem and create for 1 node .

try removing the “.” from the name space and give your namespace a name that is the same or close to your assembly name

I tried . and remove .MEP But Same Problem

then i think you can create another “baseclass” that inherits RevitDropDownBase queries all the element type based on the type that it is fed.

try this:

[NodeName("Duct Types")]
[NodeDescription("Get All Duct Type From Model Dropdown")]
[NodeCategory("DynaMEP.MEP.Ducts")]
[IsDesignScriptCompatible]
public class DuctTypes : GenericGetAllElementOfTypeDropDown
{
    private const string outPutName = "Duct Type";
    private const string NO_DUCT_TYPES = "No Duct Types Found.";

    public DuctTypes() : base(outPutName, NO_DUCT_TYPES, typeof(DuctType)) { }

    [JsonConstructor]
    public DuctTypes(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(outPutName, NO_DUCT_TYPES, typeof(DuctType), inPorts, outPorts) { }
}

public class GenericGetAllElementOfTypeDropDown : RevitDropDownBase
{
    private string NO_TYPE_FOUND { get; set; } = "No Type Found";
    private Type ClassType { get; set; }
    private SelectionState _selectionState = SelectionState.Done;

    public GenericGetAllElementOfTypeDropDown(string name, string noEnumFound, Type enumType) :
        base(name)
    {
        this.ClassType = enumType;
        this.NO_TYPE_FOUND = noEnumFound;
        PopulateDropDownItems();
    }

    [Newtonsoft.Json.JsonConstructor]
    public GenericGetAllElementOfTypeDropDown(string name, string noEnumFound, Type enumType, IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) :
        base(name, inPorts, outPorts)
    {
        this.ClassType = enumType;
        this.NO_TYPE_FOUND = noEnumFound;
        PopulateDropDownItems();
    }

    public void PopulateDropDownItems()
    {
        if (this.ClassType != null)
        {
            // Clear the dropdown list
            Items.Clear();
            Items.Clear();

            Dictionary<int, string> eleNameInt = new Dictionary<int, string>();

            using (FilteredElementCollector col = new FilteredElementCollector(DocumentManager.Instance.CurrentDBDocument).OfClass(typeof(DuctType)))
            {
                var eles = col.ToElements();
                if (!eles.Any())
                {
                    Items.Add(new DynamoDropDownItem(NO_TYPE_FOUND, null));
                    SelectedIndex = 0;
                    _selectionState = SelectionState.Done;
                }
                foreach (var ele in eles)
                    eleNameInt.Add(ele.Id.IntegerValue, ele.Name);
            }

            Items = eleNameInt.Select(x => new DynamoDropDownItem(x.Value, x.Key)).OrderBy(x => x.Name).ToObservableCollection();
            _selectionState = SelectionState.Restore;
        }
    }

    protected override SelectionState PopulateItemsCore(string currentSelection)
    {
        PopulateDropDownItems();
        return _selectionState;
    }

    public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
    {
        if (!CanBuildOutputAst(NO_TYPE_FOUND))
            return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };

        List<AssociativeNode> args = new List<AssociativeNode>()
        {
            AstFactory.BuildIntNode((int)Items[SelectedIndex].Item),
            AstFactory.BuildBooleanNode(true),
        };

        Func<System.Int32, System.Boolean, Revit.Elements.Element> func = new Func<System.Int32, System.Boolean, Revit.Elements.Element>(Revit.Elements.ElementSelector.ByElementId);

        AssociativeNode callFunctionNode = AstFactory.BuildFunctionCall<System.Int32, System.Boolean, Revit.Elements.Element>(
            Revit.Elements.ElementSelector.ByElementId,
            args
            );

        BinaryExpressionNode assign1 = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), callFunctionNode);

        return new[]
        {
            assign1
        };

        bool CanBuildOutputAst(string itemValueToIgnore = null, string selectedValueToIgnore = null)
        {
            if (Items.Count == 0 || SelectedIndex < 0)
                return false;
            if (!string.IsNullOrEmpty(itemValueToIgnore) && Items[0].Name == itemValueToIgnore)
                return false;
            if (!string.IsNullOrEmpty(selectedValueToIgnore) && Items[SelectedIndex].Name == selectedValueToIgnore)
                return false;
            return true;
        }
    }

}

Same Problem

The ‘+’ character, hexadecimal value 0x2B, cannot be included in a name