How to get Modeless form textbox value

How to get Modeless form textbox value

desdinova
Advocate Advocate
3,852 Views
14 Replies
Message 1 of 15

How to get Modeless form textbox value

desdinova
Advocate
Advocate
#region Namespaces
using System;
using System.Collections.Generic;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Architecture;

#endregion

namespace myEvent
{
    public class RoomSelectionFilter : ISelectionFilter
    {
        public bool AllowElement(Element elem)
        {
            return elem is Room;
        }

        public bool AllowReference(Reference reference, XYZ position)
        {
            return true;
        }
    }
    public class ExternalEventExample : IExternalEventHandler
    {
        private ExternalEventExampleDialog mForm;

        public void Execute(UIApplication app)
        {

            UIDocument uidoc = app.ActiveUIDocument;
            Document doc = uidoc.Document;
            string info = "";
            IList<Reference> myList = uidoc.Selection.PickObjects(ObjectType.Element,new RoomSelectionFilter(), "Pick a room");
            foreach(Reference r in myList)
            {
                Element element = doc.GetElement(r);

                using(Transaction t = new Transaction(doc,"Pick"))
                {
                    t.Start();
                    Parameter department = element.LookupParameter("Department");
                    department.Set(mForm.textBox1.Text);
                    t.Commit();

                }
                info += element.Name + Environment.NewLine;
            }
            
            TaskDialog.Show("Revit", info);
            
        }

        public string GetName()
        {
            return "External Event Example";
        }
    }

    public class ExternalEventExampleApp : IExternalApplication
    {
        // class instance
        public static ExternalEventExampleApp thisApp = null;
        // ModelessForm instance
        private ExternalEventExampleDialog m_MyForm;

        public Result OnShutdown(UIControlledApplication application)
        {
            if (m_MyForm != null && m_MyForm.Visible)
            {
                m_MyForm.Close();
            }

            return Result.Succeeded;
        }

        public Result OnStartup(UIControlledApplication application)
        {
            m_MyForm = null;   // no dialog needed yet; the command will bring it
            thisApp = this;  // static access to this application instance

            return Result.Succeeded;
        }

        //   The external command invokes this on the end-user's request
        public void ShowForm(UIApplication uiapp)
        {
            // If we do not have a dialog yet, create and show it
            if (m_MyForm == null || m_MyForm.IsDisposed)
            {
                // A new handler to handle request posting by the dialog
                ExternalEventExample handler = new ExternalEventExample();

                // External Event for the dialog to use (to post requests)
                ExternalEvent exEvent = ExternalEvent.Create(handler);

                // We give the objects to the new dialog;
                // The dialog becomes the owner responsible for disposing them, eventually.
                m_MyForm = new ExternalEventExampleDialog(exEvent, handler);
                m_MyForm.Show();
            }
        }
    }

    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
    public class Command : IExternalCommand
    {
       
        public virtual Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {

            try
            {
                ExternalEventExampleApp.thisApp.ShowForm(commandData.Application);
                return Result.Succeeded;
            }
            catch (Exception ex)
            {

                message = ex.Message;
                return Result.Failed;
            }
        }
    }
}

Hello friends 

I want to get textbox value in modeless form

How can I get the value?

Thanks in advance...Untitled-1.jpg

0 Likes
Accepted solutions (1)
3,853 Views
14 Replies
Replies (14)
Message 2 of 15

arnostlobel
Alumni
Alumni

Dear desdinova,

 

what seems to be the problem you are experiencing? Is it that you cannot find the text box, or you cannot set its value, or that you cannot get the Pick operation to work? I suspect the last one may be the culprit but I'd like you to confirm my suspicion, or deny it. Using Pick inside either Iding event or an External Event (which stems from Idling too) is problematic, because what you are basically asking Revit to do is to respond to a UI request while Revit is still waiting for the previous request (Idling) to finish.

Arnošt Löbel
Message 3 of 15

Anonymous
Not applicable
It definitely seems like pick would be an issue here. On the topic of accessing the text property of a form, if you allow VS to craft your form object, it will, by default, make all controls private data members. You may either access them via the Form::Controls property or you can set up a public string variable on your form and handle a form/control related event (e.g., TextBoxOnChange) that populates the textbox.text such that you can access that property.

That said, would definitely be curious to know what happens with the pick call...
Message 4 of 15

stever66
Advisor
Advisor

I'm somewhat new at programming and Revit, but your code is interesting because I think its very similar to a Macro I just wrote.  My Macro sets a text parameter of an element with a textbox on a windows form.

 

I'm not sure what you mean by making the "textbox modeless"?  Forms can be modeless, and your "m_MyForm.Show();" should show the form as a modeless form.   I'm not sure textboxes can be modeless.  In my code, I added "Accept" and "Cancel" buttons on the form, and then added events for those buttons to apply the textbox text to the parameter.  I also have a couple of lines that make Enter and ESC keys do the same thing as Accept and Cancel.   Is that what you are asking about? 

 

Or are you having trouble getting the text from the box to set the paramter?  I'm not quite following all your code, but I notice there is both a "mform" and a "m_MyForm". 

 

Are you using VS to set up the form?  My Macro sets up the form manually with code.   Its in python, so the formatting is a little different.  But it may be a little easier to follow what is going on than it is to understand what VS is doing?  Let me know if you would like me to post an example.

 

 

 

Message 5 of 15

desdinova
Advocate
Advocate

Thanks to all,

I think pick operation works well but i cant access the textbox value 

mForm.textBox1.Text 

 returns no value

I think ExternalEventExampleDialog is an issue here.

I attach the source code 

0 Likes
Message 6 of 15

Anonymous
Not applicable

 

My eyes may be deceiving me but it looks like you've declared mForm as a private data member on your external event and then never assigned it anything.  It should be null at the time you try to call it...

 

At the same time you've made the form on your app a private data member so you won't be able to access it anyway

 

Try this hack: (fix the poor coding standard as appropriate)

public static ExternalEventExampleDialog m_MyForm;

Then in Event Handler:



public class ExternalEventExample : IExternalEventHandler { private ExternalEventExampleDialog mForm; public void Execute(UIApplication app) { UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; try { while (true) { Reference r = uidoc.Selection.PickObject(ObjectType.Element, new RoomSelectionFilter(), "Pick"); Element element = doc.GetElement(r); using (Transaction t = new Transaction(doc, "Pick")) { t.Start(); Parameter department = element.LookupParameter("Department"); department.Set(ExternalEventExampleApp.m_MyForm.textBox1.Text); t.Commit(); } } } catch { } } public string GetName() { return "External Event Example"; } }

 

Note that this is kind of a hack (if it even works... I'm still trying to figure out why you aren't getting null exception when trying to access that textbox)

More appropriately, you should add a public string variable to your form which gets populated by the button click event and then you can read it in your event handler (I think).  Or maybe better yet, if you want the form to remain private, put a public string on your app that the form can fill out.

 

Are you not getting exceptions when you run this?

 

 

 

Message 7 of 15

stever66
Advisor
Advisor

I would also suggest temporarily adding in some task dialog boxes to aid in troubleshooting:

 

Add a TaskDialog.Show("The Textbox Text is:"mForm.textBox1.Text)

 

And TaskDialog.Show("The current Parameter is:"department.AsString())

 

I would add these when you first get the text or data, and again before making the assignment to make sure everything is still in scope.

 

Of course, once you have everything working, you can delete these or comment them out.

 

Message 8 of 15

desdinova
Advocate
Advocate

Hi Ken

I get "An object reference is required for the non-static field, method, or property 'myEvent.ExternalEventExampleApp.m_MyForm'" exception.

0 Likes
Message 9 of 15

Anonymous
Not applicable
Accepted solution
yup that's no surprise. It's not really a good idea anyway. Why don't you put a static string on the app and populate it from the dialog onClick handler.

in App:
public static string myTextInfo

in form
OnClick()
{
App.myTextInfo = TextBox1.Text;
}
Then in the event department.Set(App.myTextInfo);
Message 10 of 15

desdinova
Advocate
Advocate

Thank you so much  Ken 

That worked...

And thanks to all.

0 Likes
Message 11 of 15

desdinova
Advocate
Advocate

One more question 

When i press the addin button i get this error

error.jpg

How can i solve this 

Thanks in advance...

0 Likes
Message 12 of 15

stever66
Advisor
Advisor

It sounds like your code is trying to set a parameter or lookup a parameter for a variable that doesn't contain a valid Revit element.

 

I would suggest trying to narrow down exactly which line of code is causing the error.  You can use breakpoints in VS, or step through the program one line at a time.

 

Or, as i mentioned earlier, you can also use Taskdialog boxes to verify the code has ran to a certain point, and to display the contents of variables at that point.

 

Message 13 of 15

desdinova
Advocate
Advocate
Thank you stever66
I solved the problem
It was about the addin file
I added ExternalEventExampleApp : IExternalApplication class the addin file
and it is Ok.
0 Likes
Message 14 of 15

MGO-Norsyn
Advocate
Advocate

Thank you for this thread and provided sample source code -- it really helped me wrap my head around the concept and complete my own modeless form. The modeless samples in SDK are hard to understand, so this thread was a really big help. Thank you.

0 Likes
Message 15 of 15

SONA-ARCHITECTURE
Advocate
Advocate

Hi everybody 

I’m asking me a question: public static string mTextinfo in ExternalEventExempleApp is a solution to update an element into the UI form. But is it clean? If I want to update lot of components into Ui? How to do it in best way ?

Pierre NAVARRA
SONA-Architecture.
http://www.sona-architecture.com
https://fr.linkedin.com/in/pierre-navarra-62032a107
0 Likes