get_Parameter().Set value lost

get_Parameter().Set value lost

RickyBell
Enthusiast Enthusiast
2,070 Views
7 Replies
Message 1 of 8

get_Parameter().Set value lost

RickyBell
Enthusiast
Enthusiast

I have a program that writes parameter data back to Revit, it works.  But it appears that if I don't immediately save the project, I lost that data if I move around the project.  IdentityData.Comments for example.  If I enter a family, assembly, change views, etc.  The data is blank again.  Any advice is appreciated, Thanks!

 

ex. 

try {

ele.get_Parameter("Comments").Set(this.txtComments.Text);

MessageBox.Show("Updated!");

} catch {
MessageBox.Show("Value is Read Only.");

}

0 Likes
Accepted solutions (1)
2,071 Views
7 Replies
Replies (7)
Message 2 of 8

arnostlobel
Alumni
Alumni
RickyBell:

You do not have to save the document, but you have to commit the transaction within which you modified the model. If you do not do that, some other activity would cancel your transaction which would lead to loosing all changes you have made.

By the way: I do not understand the code snippet you posted. Where is your transaction there and why does the message shows the text it does?

Thanks

Arnošt Löbel
Autodesk, Revit R&D
Arnošt Löbel
0 Likes
Message 3 of 8

RickyBell
Enthusiast
Enthusiast

Thanks for the reply.

 

I was just showing the method of which I'm setting the parameter value.  It was just to help you understand what I'm attempting to do.

 

Since I'm just using the single line, get_Parameter("Comments").Set, how you do you suggest I commit the transaction?

0 Likes
Message 4 of 8

arnostlobel
Alumni
Alumni
Accepted solution
Well, my answer depends a lot on how your application is structured, about which I have no knowledge whatsoever at this point. However, generally there must be a transaction around any attempt to change the model, and the transaction must be committed (Transaction.Commit()) in order for the changes to be accepted. For example, if your code is in an external command that uses a Manual TransactionMode (always proffered a mode), at some point before you start making changes, you must start the transaction (Transaction.Start()) and only then you can set new values to the parameter. Please look into the SDK documentation for the Transaction class - I believe it has quite extensive information.

Thanks

Arnošt Löbel
Autodesk, Revit R&D
Arnošt Löbel
0 Likes
Message 5 of 8

RickyBell
Enthusiast
Enthusiast

You got me on the right track, thanks.  I changed transaction mode to manual.  I'm running into this issue now.

 

"Starting a transaction from an external application running outside of API context is not allowed."

 

After reading other posts and the documentation, I realize why.  So I put this code right into the main class:

 

           Transaction setTransaction = new Transaction(doc, "Update Parameters");  //not sure what this string value is for.
            setTransaction.Start();

            //Open the form
            frmMain varForm = new frmMain();
            varForm.ShowDialog();      // form appears, I can make changes to parameters.. everything is happy.
            setTransaction.Commit();      //crashes Revit.

 

I'll keep trying examples from the documentation.  Any ideas?

0 Likes
Message 6 of 8

arnostlobel
Alumni
Alumni

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:

 

  1. 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).
  2. 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
0 Likes
Message 7 of 8

RickyBell
Enthusiast
Enthusiast

That was it.  varForm.ShowDialog() vs varForm.Show().

 

I was using the Application.Exit on my close button and it wasn't completing the code from my Class.  Changed that to this.Close() and we're all set.

 

Changes are being commited now, Thanks so much for your help.

0 Likes
Message 8 of 8

arnostlobel
Alumni
Alumni
I am glad to hear you found a fix. 🙂
My suggestions are still valid though and I would recommend looking into it if you want to make your application more stable. Particularly the putting all transactions into their respective using blocks (in C# and VB) is a thing I cannot recommend strongly enough. Also, having transactions as close as possible to changes where they are actually made will make your code more maintainable going forward.

Arnošt Löbel
Autodesk, Revit R&D
Arnošt Löbel
0 Likes