Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Creating a TextNote with the 2016 API changes.

18 REPLIES 18
SOLVED
Reply
Message 1 of 19
Anonymous
8785 Views, 18 Replies

Creating a TextNote with the 2016 API changes.

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

18 REPLIES 18
Message 2 of 19
arnostlobel
in reply to: Anonymous

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.

Arnošt Löbel
Message 3 of 19
Anonymous
in reply to: arnostlobel

Thank you so much, only been at this two weeks and I'm trying to learn as much as I can. This is a great help.

Message 4 of 19
Anonymous
in reply to: arnostlobel

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!

Message 5 of 19
arnostlobel
in reply to: Anonymous

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.

Arnošt Löbel
Message 6 of 19
Anonymous
in reply to: arnostlobel

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!

Message 7 of 19
Anonymous
in reply to: arnostlobel

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!

Message 8 of 19
Anonymous
in reply to: Anonymous

As I said: amateur question.....

 

Final code line: note = TextNote.Create(uiDoc.Document, uiDoc.ActiveView.Id, endPoint, noteWidth, noteValue, noteOptions);

 

Works like a charm.

Message 9 of 19
arnostlobel
in reply to: Anonymous

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

Arnošt Löbel
Message 10 of 19
Anonymous
in reply to: arnostlobel

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. 

Message 11 of 19
arnostlobel
in reply to: Anonymous

Hello crobertsnc:

Before I get to commenting on your last post, let me copy and paste a piece from the documentation of the TextNote.Create method:

"Width [ft] of the text in paper space (i.e. as it is measured when printed.) If a line of text is longer than the given specified Width, the text will be automatically wrapped. If a zero Width is supplied then this method will create an unwrapped text note element."

What that statement means is that the side we assign to a text note really is related to the paper when the view in which the text note sits it printed. Also important is the fact that the value is in feet no matter what the current units are assigned to the project. So, to use an example, if the scale of the view is, say 1:200, then a text note with assigned width 1.0 (= 1 foot) will be measured 200 feet in the model (if you use a dimension or the measurement tool). Only when the view is printed and scaled down to its final size (on paper) the text will be printed 1-foot wide. Revit takes care of automatic adjustment in the case the view's scale changes; however, the printed size will always be the same (1.0 foot in our example) no matter what the scale is.

In the light of these facts, the screen-shot you uploaded cannot tell us a lot, for it is not at all obvious what scale and units you actually use in that view.

I do not understand your comment about the attachment. Text notes do not have vertical alignment. Text content within a text note's box is always aligned vertically to the top of the box. It can only be aligned horizontally - Left, Center, or Right, respectively.

Thank you
Arnošt Löbel
Message 12 of 19
Anonymous
in reply to: arnostlobel

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...

Message 13 of 19
arnostlobel
in reply to: Anonymous

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.

 

TextNoteSample.png

 

 

 

 

 

 

 

Arnošt Löbel
Message 14 of 19
Anonymous
in reply to: arnostlobel

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!

Message 15 of 19
Anonymous
in reply to: Anonymous

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

Message 16 of 19
Revitalizer
in reply to: Anonymous

TextNote.Coord




Rudolf Honke
Software Developer
Mensch und Maschine





Message 17 of 19
Anonymous
in reply to: Revitalizer

Thanks, I am blind

Message 18 of 19
Anonymous
in reply to: arnostlobel

The class factory method Document.Create.NewTextNote() uses TextAlignFlags to determine aligment. This has bitfields for both horizontal and vertical alignment. Is it correct that the flags for vertical alignment were ignored? Also, the class factory has parameters for the base and up vectors. I am curious to know what they have been replaced with in the TextNoteOptions? Mark de Vries ICN Solutions b.v.
Message 19 of 19
Anonymous
in reply to: Anonymous

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.

Post to forums  

Autodesk Design & Make Report