RickyBell:
Well, I cannot tell from just the info you provided, but I am sure we'll get there one way or another.
The code appears all right. The dialog is modal, thus it executes on the same thread and therefore is allowed to make changes to the document. You have a transaction around it, so the changes may actually be made, and you have code that commits it. So far so good.
Now, let's eliminate what could go wrong.
I have no idea what exactly you do in the dialog, so it is hard to guess why committing the transaction would fail. To get a better idea, please do the following:
- Make sure you put the transaction in a using block as illustrated in the documentation. That eliminates the case when if an exception happens because of an illegal change and leaves undisposed transaction hanging around (uncollected by the garbage collector).
- Secondly, please add some try-catch block around the whole thing and display a message from the catch block (I assume you getting exception is what you meant by stating that Revit crashes).
This should push us a bit further to figuring out what might go wrong. (By the way, it is really unusual for Transaction.Commit to throw. Are you sure it is the Commit method and not your dialog’s execution that actually throws?)
As a separate improvement, which you can make later, it is always recommended to use transactions as close to the model changes as possible. That means you do not have to have it in the main ExternalCommand.Execute method. You can have it right in the dialog wherever you actually make the changes. You create a transaction there, start it and commit it there too. Just make sure that the transaction is in a using block (I really insist on that part, don’t I 🙂
All this is of course applicable only if the dialog is modal, which I assume it is. Modeless dialogs must follow an entirely different strategy. Am I right about the dialog? I am asking because I am still puzzled by your mentioning the exception "Starting a transaction from an external application running outside of API context is not allowed." I do not understand how could you get there under normal circumstances and how could it be “fixed” (quotes intended) by moving your transaction from a modal dialog to the main Execute method of an external command. (You actually did not mention that it is the Execute method, but I am assuming it is.) Practically the only way for you to get this kind of exception is when you launch off a modeless dialog (from the Execute method or from OnStartup) and after that Execute method (or whatever) returns, you attempt to start a transaction from the now dangling modeless dialog. Since that dialog would at that time had nothing to do with Revit, we do not allow calls from it to be executed in the API.
Arnošt Löbel
Sr. Principal Engineer, Revit
Arnošt Löbel