Delegating strategy selection to WinForms

Delegating strategy selection to WinForms

shevyakov.a
Contributor Contributor
426 Views
3 Replies
Message 1 of 4

Delegating strategy selection to WinForms

shevyakov.a
Contributor
Contributor

Hello!

 

I'm trying to create GUI that will gently guide Add-in users through a chain of commands. So far, I've found myself in a middle of nowhere.

I'm acknowledged of inavailability to execute commands outside RevitAPI context, and I've thought of a way of dealing with it. I've created one main implementation of IExternalCommand and incapsulated all of the logic into instances of Base_Routine class. I want user to set behaviour of the routine with the help of my GUI. Here's my code snippet 

 

    [Transaction(mode: TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    class Run : IExternalCommand
    {
        private Base_Routine RoutineBehaviour;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {

            SetRoutineBehaviour();

            RoutineBehaviour.ExecuteRoutine(commandData);

            return Result.Succeeded;

        }

        private void SetRoutineBehaviour()
        {
            System.Windows.Forms.Form landing = new GUI.Landing();
            if (landing.ShowDialog() == System.Windows.Forms.DialogResult.OK);
            //Some code here that sets behaviour

        }

 GUI.Landing form is supposed to call for another Form after i click a button on it. However, another form doesn't open and a NullReferenceException is thrown. Right now I'm struggling to understand whether this approach will give any result (the reason behind that is my basic level of programming proficiency), so I have a couple of questions:

 

1. Is the generall approach correct? Or should I take a closer look at the IExternalEventHandler? 

if (the approach is correct){

2. Should i create a separate thread for my forms-based GUI or is MTAthread by default enough? What should I do with them? How should I handle them? (I have basically no understanding on how threads work, so any help in this area is appreciated)

3. Are there any examples or related articles i should study? I've read a couple of them from https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.28 but I don't fully understand if any of these solutions are suitable for what I'm trying to do

 

Much appreciation

 

0 Likes
Accepted solutions (1)
427 Views
3 Replies
Replies (3)
Message 2 of 4

jeremy_tammik
Alumni
Alumni
Accepted solution

That sounds like an interesting question, possibly somewhat complex, and almost certainly with many possible answers.

 

If I understand you correctly, you want to guide the user through a sequence of steps.

 

I also assume that each of these steps requires interaction with the Revit API.

 

If those two conditions are true, you have exactly two options:

 

  • Simple: remain completely within the single-threaded modal Revit API context provided by your external command at all times. Do not return from the external command until the process is completed. The user cannot interact with Revit until after your external command has completed.
  • Complex: implement a modeless mainline for your sequence of commands. The user can continue interacting with Revit in parallel with your UI. You have no access to the Revit API from the modeless context, except through the implementation and execution of external events.

 

I believe that both these approaches are demonstrated by various Revit SDK samples.

 

For the former, there are probably several that you can take a look at, and I believe that the WindowWizard sample is one of them.

 

For the latter, being more complex to implement, there is only one: ModelessDialog/ModelessForm_ExternalEvent.

 

I hope this helps you get started and wish you lots of fun and flexibility and good longterm vision choosing which path to take.

 

If you are not very familiar with these concepts and their realisation in the Revit API and you really want to create an optimal solution, I would recommend that you try out both of these paths. That would not be all that hard to do, and a very interesting exercise that I would be glad to support and help document.

 

Good luck and best regards,

 

Jeremy

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 3 of 4

jeremy_tammik
Alumni
Alumni

Actually, maybe the approach you describe yourself suggests a third possibility:

 

A modal external command that in turn can launch other modal commands. You can actually launch both you own external commands and built-in Revit ones using PostCommand. That would indeed enable chaining a sequence of modal external commands, if you wish.

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 4 of 4

shevyakov.a
Contributor
Contributor

Thanks a lot! Seems like WindowWizard is exactly what i need. Would surely try it first, and then check other options 

0 Likes