ComboBox and Modeless Form - Getting error (Object reference not set...)

ComboBox and Modeless Form - Getting error (Object reference not set...)

tiagofrbr
Contributor Contributor
449 Views
5 Replies
Message 1 of 6

ComboBox and Modeless Form - Getting error (Object reference not set...)

tiagofrbr
Contributor
Contributor

Hi!
I've seen the post about this topic in the links below:
https://forums.autodesk.com/t5/revit-api-forum/modeless-form-and-combobox/td-p/9119051.
https://forums.autodesk.com/t5/revit-api-forum/how-to-retrieve-modeless-form-s-combobox-s-text-in-ex...

However I couldn't figure it out in my code how to get data into my combobox, getting the same error: "Object reference not set to an instance of an object".

Hope someone can help me...

tiagofrbr_0-1733009874113.png

 

Command.cs

 

namespace ElectricalDiagrams
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public virtual Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            try
            {
                App.thisApp.ShowForm(uiapp);
                return Result.Succeeded;
            }
            catch(Exception ex)
            {
                message = ex.Message;
                return Result.Failed;
            }
        }
    }
}

 

 

App.cs

 

namespace ElectricalDiagrams
{
    public class App : IExternalApplication
    {
        internal static App thisApp = new App();
        private ModelessForm form;
        public Result OnStartup(UIControlledApplication application)
        {
            form = null;
            thisApp = this;
            return Result.Succeeded;
        }
        public Result OnShutdown(UIControlledApplication application)
        {
            if (form != null && form.Visible)
            {
                form.Close();
            }
            return Result.Succeeded;
        }
        public void ShowForm(UIApplication uiapp)
        {
            if (form == null || form.IsDisposed)
            {
                RequestHandler handler = new RequestHandler();
                ExternalEvent exEvent = ExternalEvent.Create(handler);
                form = new ModelessForm(exEvent, handler);
                form.Show();
            }
        }
        public void WakeFormUp()
        {
            if (form != null)
            {
                form.EnableCommands(true);
            }
        }
    }
}

 

 

 RequestHandler.cs

 

namespace ElectricalDiagrams
{
    public class RequestHandler : IExternalEventHandler
    {
        private Request request = new Request();
        public Request Request { get { return request; } }
        public string GetName()
        {
            return "External Event";
        }

        public void Execute(UIApplication uiapp)
        {
            try
            {
                switch (Request.Take())
                {
                    case RequestId.None:
                        {
                            return;
                        }
                    case RequestId.GetPanels:
                        {
                            new GetPanels(uiapp, PanelComboBox);
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }
            }
            finally
            {
                App.thisApp.WakeFormUp();
            }
            return;
        }
    }
}

 


Request.cs

 

namespace ElectricalDiagrams
{
    public enum RequestId : int
    {
        None = 0,
        GetPanels = 1
    }
    public class Request
    {
        private int request = (int)RequestId.None;
        public RequestId Take()
        {
            return (RequestId)Interlocked.Exchange(ref request, (int)RequestId.None);
        }
        public void Make(RequestId requestId)
        {
            Interlocked.Exchange(ref request, (int)requestId);
        }
    }
}

 

 

ModelessForm.cs

 

namespace ElectricalDiagrams
{
    public partial class ModelessForm : Form
    {
        //private Document doc;
        private RequestHandler requestHandler;
        private ExternalEvent externalEvent;
        public ModelessForm(ExternalEvent exEvent, RequestHandler handler)
        {
            InitializeComponent();
            requestHandler = handler;
            externalEvent = exEvent;
        }
        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            externalEvent.Dispose();
            externalEvent = null;
            requestHandler = null;
            base.OnFormClosed(e);
        }
        public void EnableCommands(bool status)
        {
            foreach (Control control in this.Controls)
            {
                control.Enabled = status;
            }
            if (!status)
            {
                this.CancelButton.Enabled = true;
            }
        }
        private void MakeRequest(RequestId requestId)
        {
            requestHandler.Request.Make(requestId);
            externalEvent.Raise();
            EnableCommands(false);
        }
        private void ModelessForm_Load(object sender, EventArgs e)
        {
            MakeRequest(RequestId.GetPanels);
        }
        private void CancelButton_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}

 

 

GetPanels.cs

 

namespace ElectricalDiagrams.Extensions
{
    class GetPanels
    {
        public GetPanels(UIApplication uiapp, System.Windows.Forms.ComboBox PanelComboBox)
        {
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Document doc = uidoc.Document;
            IList<Element> panelElements = new FilteredElementCollector(doc).
                OfCategory(BuiltInCategory.OST_ElectricalEquipment).
                WhereElementIsNotElementType().
                ToElements();
            List<string> panelNames = new List<string>
                (panelElements.Select<Element, string>(e => e.Name.ToString()));
            try
            {
                PanelComboBox.DataSource = panelNames;
            }
            catch (Exception ex)
            {
                TaskDialog.Show("Error", ex.ToString());
            }
        }
    }
}

 

0 Likes
450 Views
5 Replies
Replies (5)
Message 2 of 6

scgq425
Advocate
Advocate

Hi @tiagofrbr :

are you debug this code ? and which row post this error? 

this code logic like run the command and collected electraic data to combobox?

LanHui Xu 徐兰辉
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Blog
LinkedIn
Revit/CAD Development | Steel Product Manager

EESignature

0 Likes
Message 3 of 6

tiagofrbr
Contributor
Contributor

Yes I did. The row which posts this error is the row 24 from RequestHanlder.cs. The code logic was able to collect the electric data into the combobox, but I found that the issue is that the code at the row 24 from RequestHandler couldn't find the reference for "PanelComboBox", which is the combobox I created in my Modeless Form.

new GetPanels(uiapp, PanelComboBox);
0 Likes
Message 4 of 6

reylorente1
Collaborator
Collaborator

I've been checking your code, I don't master the electrical part of Revit. Add this part to the code, see if it works

public void Execute(UIApplication uiapp)
{
    try
    {
        switch (Request.Take())
        {
            case RequestId.None:
                {
                    return;
                }
            case RequestId.GetPanels:
                var form = Application.OpenForms.OfType<ModelessForm>().FirstOrDefault();
                if (form != null)
                {
                    // Llama a la función para llenar el ComboBox  
                    form.Invoke((MethodInvoker)delegate
                    {
                        new GetPanels(uiapp, form.PanelComboBox);
                    });
                }
                break;
            default:
                {
                    break;
                }
        }
    }
    finally
    {
        App.thisApp.WakeFormUp();
    }
    return;
}
0 Likes
Message 5 of 6

scgq425
Advocate
Advocate

Hi @tiagofrbr :

i test you code is run ok, i get all electric data and post to combobox . but in you code , i add this paramater to trans PanelCombobox .

and in the link file i push the project you can re-build and debug this .

 public class Value
 {
     public static System.Windows.Forms.ComboBox PanelComboBox;
 }

 

 public ModelessForm(ExternalEvent exEvent, RequestHandler handler)
 {
     InitializeComponent();
     requestHandler = handler;
     externalEvent = exEvent;
     Value.PanelComboBox = this.PanelComboBox;
 }

. i push  

LanHui Xu 徐兰辉
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Blog
LinkedIn
Revit/CAD Development | Steel Product Manager

EESignature

0 Likes
Message 6 of 6

tiagofrbr
Contributor
Contributor

Thanks for your help! Here's the solution that I found to be working:

 

public ModelessForm(ExternalEvent exEvent, RequestHandler handler, UIApplication Uiapp)
{
    InitializeComponent();
    requestHandler = handler;
    externalEvent = exEvent;
    uiapp = Uiapp;
    requestHandler.GetPanelComboBox = PanelComboBox;
}

 

 

 

public class RequestHandler : IExternalEventHandler
{
    public ComboBox GetPanelComboBox { get; set; }
}

 

0 Likes