Hi,
I am a newbie with the Revit API and I want to create a textnote on a sheet. I have seen sample codes using the old methods but. TextNote.Create() has just been introduced and seeing a sample code using this method will help me understand it and allow me implement my version.
Thank you,
Jack
Solved! Go to Solution.
Solved by arnostlobel. Go to Solution.
Hello Jack,
there are four new Create methods added in the R2016 API for Text notes. I believe all of them are rather simple and straightforward to use. I'll show two code snippets here, but I am positive you will have no problems to adjust it to your concrete needs:
This one snippet creates a text note which has an adjustable width (width that grows with the text contained withing). Typically, this creation method is used for creating one-line annotations. In this particular snippet I use the currently default TextNoteType, but you can use any other available text-note-type if you wish so.
using (Transaction tran = new Transaction(RevitDoc, "Creating a Text note")) { XYZ origin = new XYZ(10, 10, 0); ElementId defaultTypeId = RevitDoc.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType); tran.Start(); TextNote note = TextNote.Create(RevitDoc, someView.Id, origin, "Text Note", defaultTypeId); tran.Commit(); }
The next snippet shows creating a text box - that is a text note with a fixed width, as is normally created vi the UI when the end-user specifies the box of the new text note. Text content then wraps inside the box and extends the box' height if needed. The box' size can be controlled via the UI later after creation using the control points of the box. Also, in this example I show how to use the options to change some of the default properties of the new text object - the alignment in this particular case.
using (Transaction tran = new Transaction(RevitDoc, "Creating a Text note")) { XYZ origin = new XYZ(10, 10, 0); double width = 3.0 / 12.0; // feet on paper TextNoteOptions options = new TextNoteOptions(); options.HorizontalAlignment = HorizontalTextAlignment.Center; options.TypeId = RevitDoc.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType); tran.Start(); TextNote note = TextNote.Create(RevitDoc, someView.Id, origin, width, "Text Box Content", options); tran.Commit(); }
I hope this helps and you and others find it useful.
This is very helpful, thank you. I'm working on updating a code snippet from 2015 to 2016 capatibility. Basic functionality, but the removal of uiDoc.Document.Create.NewTextNote() threw me. I've updated to TextNote.Create(), but am having trouble passing the first variable correctly. In the code snippet above your passing a declared variable of RevitDoc, but I'm not sure how that's being defined, and am having trouble getting my necessary definition created.
Previously, I was passing the uiDoc.ActiveView as my view to Create.NewTextNote but the uiDock.ActiveView isn't (obviously) a Document which I'm seeing is the first required arguement for the new. I'm a newbie to coding for Revit so I sincerely appreciate any help you can provide. Thank you in advance!
Hello crobertsns:
I am sorry I wasn't more explicit about the variables I used in my snippets. I took them directly from our API tests and did not realize that certain "adjustments" may be needed. In our tests RevitDoc is a global variable representing a Revit Document (API class) that is being tested. You can get an instance of Document from your UIDocument by accessing the Document property - in your case uiDoc.Document.
By the way, I do not believe we actually remove the method NewTextNote, did we? (I cannot check at this very moment, but I'll check tomorrow.) I remember I myself marked it deprecated and left it there. It was sometime last year, thus it should still be available in R2016 (it will not be in 2017). Not surprisingly, it internally uses the new TextNote.Create method.
Excellent, that helps me to solve that issue - never helps when you're new to Revit coding and editing someone else's existing code! Thank you.
You're correct, it has only been deprecated, but I need to update this .addin for new install paths so I opted to go ahead and upate this as well as way to make sure next year it's a very simple update. This way I can always fall back to the old code if needed. Not to mention, a good opportunity to learn!
What's really being a pain in my side is Visual Studio seems to be 'choosing' the wrong overladed method and I can't wrestle it back to what I want.
Here's my line:
note = TextNote.Create(uiDoc.Document, uiDoc.ActiveView, endPoint, noteWidth, noteValue, noteOptions);
Where uiDoc is the active document, endPoint is an XYZ value delcared via user click, noteWidth is a double that is based on current scale, noteValue is a string, and noteOptions is a TextNoteOptions with a few parameters. This seems (to my amateur self at least) to be valid use of TextNote.Create (there's four options, and this is the fourth). Any insight into why this would show as having invalid arguements?
I know these are easy questions, I appreciate the help from anyone that can give!
As I said: amateur question.....
Final code line: note = TextNote.Create(uiDoc.Document, uiDoc.ActiveView.Id, endPoint, noteWidth, noteValue, noteOptions);
Works like a charm.
And that is correct. I am glad that you have figured it out. I'd expect the compiler to give you better hints, but I might overestimate its functionality. I have always thought that compiler errors in VS were rather good, but they can be probably overwhelming for a novice programmer.
It would definitely be helpful to you to keep the RevitAPI.CHM (from the SDK folder) help file handy and open while your are coding and learning. You should not need to depend on compiler errors. One look at the description of of the TextNote.Create method should make it clear enough what arguments are needed and expected.
With this new TextNote.Create method you have learned about two of our API patterns that we have been pushing in recent years:
a) We tend to put static Create methods to the classes of which instances may be created by users (e.g. Elements)
b) We often prefer (but not always) working with element Ids rather than Elements directly, It is to safe memory and (possibly) increase performance. We (Revit programmers) use this approach almost exclusively in Revit's internal code.
Cheers
So, I got all of this updated, after just a little fighting (and a lot of learning). There are still two main things I'm having trouble really getting to work the way I want them to.
1. The width of the note is created gigantic... I have tried modifying this parameter (I'm passing it as a declared variable now, but have tried just using 1.0 and 0.1 with no change).
Line passed: note = TextNote.Create(uiDoc.Document, uiDoc.ActiveView.Id, endPoint, 0.1, noteValue, noteOptions);
Even at 0.1 the text note is tremendouly large - I've attached an image just to show.
2. The user is requesting that the Note be attached top left and top right (currently it's bottom right). I've updated to make to top left (that was easy), but the additional requirement of bottom right is throwing me a bit. All I see available as TextNoteOptions is HorizontalAlignment ....
Thank you in advance.
Thank you for the response, you've hit on excatly what I'm struggling with... The width is determined by paper size, that's not an issue. The issue is even at 1/8" scale it's making a note that's much wider than the text, and view. The stranger thing (for me trying to understand this) is when I use Revit Snoop the Text Note Width is always 0.44.... regardless of the actual width of the note so no matter how I edit (or define) the width of that TextNote it's always reading as the same size so I'm just stuck with this.
Using the deprecated Create.NewTextNote we passed a hardcoded width of 1.0, here's the snippet:
note = uiDoc.Document.Create.NewTextNote(uiDoc.ActiveView, endPoint, uiDoc.ActiveView.RightDirection, uiDoc.ActiveView.UpDirection, 1.0, alignFlags, noteValue); where everything else is defined previously. When I maintain this call instead of the new TextNote.Create() I have the same issue... This is happening at many different scales and views.
I feel like I'm just missing an overall understanding of something here, but I can't determine what it is - the create.newtextnote() call above works absolutely as expected in 2015, and not in 2016...
crobertsnc:
unfortunately, there is not a lot I can do with just the snippet you posted. without having you actual document with the note I cannot do any examination. Like I said, the width will depend on your scale and your units.
What I can do, however, is to share my code and show you what it does.
First of all, I do not use the old method anymore and I suggest you do not use it either. Here is a simple macro that I have just created. I tried to use data similar to what you said you had:
public void NewBoxTextNote() { UIDocument uidoc = this.ActiveUIDocument; if (uidoc == null) { TaskDialog.Show("Error", "No document is currently open!"); return; } XYZ position = XYZ.Zero; double width = 1.0; // <== 1.0 feet on paper string text = "My Text Note"; ElementId textType = uidoc.Document.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType); using (Transaction trans = new Transaction(uidoc.Document, "New Text Note")) { trans.Start(); TextNote.Create(uidoc.Document, uidoc.ActiveView.Id, position, width, text, textType); trans.Commit(); } }
It creates a text note that is one foot wide. My document was based on the default US template which has default 1:96 scale and uses feet as main units. Therefore, when I measure the created text, I get something like 97.28 feet - that is because of the scale plus a bit of extra because of the text-box' border.
I'll try to upload a screen shot. The dimensions are barely readable, but you can still see the dimension is over 97 and the view scale is 1:96.
Ok, thank you for your patience here - a simple error of me not paying attention. It works now! here's a snippet with a bit more information:
UIDocument uiDoc = commandData.Application.ActiveUIDocument; noteValue = noteValue.Replace("\"\"", "\""); double widthNote = 1.0 / 12.0; ElementId textType = uiDoc.Document.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType); note = TextNote.Create(uiDoc.Document, uiDoc.ActiveView.Id, endPoint, widthNote, noteValue, textType);
I left the noteValue as just the last line since that's looking up text from an external file and works as is.
Now I have another fun thing going on with the leaders, but I'll posted that on a different thread since my issue here has been solved. Again, thank you!
Does anybody know if its possible to get the XYZ of an existing Textnote?
I have tried using TextNote.Location as LocationPoint but it is a null value.
foreach (Element e in TextNotes) { if (e is TextNote) { TextNote tx = (TextNote)e; using (Transaction tran = new Transaction(doc, "Creating a Text note")) { LocationPoint origin = tx.Location as LocationPoint; XYZ originXYZ = origin.Point; // null value!! }
}
}
Thanks,
Jack
I am updating an older Add-In that worked fine in R14. I cannot get the text to show up. I even created a new test project with only the initial example from this thread. It compiles and runs without errors, but does not create the text note. One of my other add-ins didn't work either because of where you edit the document from. Is that the case with this? Would someone be willing to bundle their example for me to take a look at? Thanks.
Can't find what you're looking for? Ask the community or share your knowledge.