Document Elements

We have already used the Document.Elements property a couple of hundred times in previous posts to this blog, so this explanation is rather belated, but addresses a question that does keep on popping up from time to time anyway:

Question: How can I access the Document.Elements property in C#?

The Revit help document lists the property named Document.Elements, stating that it is an overloaded property providing access to a set of elements from the document. The overloads are listed as

  • Elements: Provides access to all elements within the document.
  • Elements( Filter ): Provides access to all elements which satisfy specified filter.
  • Elements( Type ): Provides access to all elements of specified type.
  • Elements( Filter, ElementArray ): Collects all elements which satisfy specified filter.
  • Elements( Filter, ICollection of Element ): Collects all elements which satisfy specified filter.
  • Elements( Type, ElementArray ): Collects all elements which satisfy specified type.
  • Elements( Type, ICollection of Element ): Collects all elements which satisfy specified type.

However, when I try to access these properties in C#, the Visual Studio compiler reports an error and says that they do not exist.
How can I access these properties in C#?

Answer: You can look at the C# source code generated automatically by the definition of the Document class by Visual Studio, by positioning the cursor over the Document type and pressing F12.
This shows a completely different list of overloads:

  • public ElementIterator Elements;
  • public ElementIterator get_Elements( Filter );
  • public ElementIterator get_Elements( Type );
  • public int get_Elements( Filter, ElementArray );
  • public int get_Elements( Filter, ICollection );
  • public int get_Elements( Type, ElementArray );
  • public int get_Elements( Type, ICollection );

As you can see, only the Elements property with no filter or type argument is available using the name given in the help file.
The other Document.Elements members are considered to be methods, not properties, and have therefore been automatically decorated with the accessor prefix “get_”.
To call them, you need to prepend “get_” and obviously also provide the required arguments.

Question: How can I access the Document.Elements property in VB?

I have converted some C# sample the code to VB but have an error with a function in the line


m_doc.getElements(viewFilter, views)

The error states that .GetElements is not a member of Autodesk.Revit.Document, although I have defined m_doc as an Autodesk.Revit.Document.

Answer: You can use the Visual Studio Intellisense functionality or the object browser to determine the real name of the method you are trying to invoke in whatever language you prefer to use.

The method or property you are accessing is called Elements in the Revit API help. In C#, it is accessed using the call


m_doc.get_Elements(viewFilter, views);

In VB, you have to drop the “get_” prefix, so the call is


m_doc.Elements(viewFilter, views)

Reply: Thanks for the response.
I did try with Elements, but this causes an error saying “property access must assign to the property or use its value”, as it is returning an Integer.
This problem goes away if I use


Dim i as Integer = m_doc.getElements(viewFilter, views)

What are we using the return value from this line for anyway?

Answer: Oops, yes, right you are.
The return value of these properties is the number of elements matching the specified criteria.

In VB, this is a read-only property, and the VB syntax requires you to make use of it as such.
This means that you must read the value returned by the property, regardless of whether you make use of it or not.

Maybe this is part of the reason why these members are considered methods instead of properties in C#.
In C#, you are not forced to read the return value, but you can, if you like.


Comments

7 responses to “Document Elements”

  1. Jeremy,
    How could the Elements or get_Elements() return and iterator while the Document class does not implement IComparable. (according to the help file that comes with Revit SDK)
    Thanks in advance.

  2. Dear Nadim,
    “Ours is not to wonder why, ours is but to do or die.”
    That’s the way it is, take it or leave it. It works.
    Cheers, Jeremy.

  3. I will take it anyway.
    It is just that I have been studing .NET collections and enumration for days, and the Autodesk.Revit.Document class confused me because it does not implement IEnumrable or IEnumerableT, yet we still can enumerate through its elements using get_Elements() or Elements property.
    Thanks,
    Nadim

  4. Dear Nadim,
    I see what you mean now. Well, the Elements property returns an iterator. The document itself is not an iterator.
    Cheers, Jeremy.

  5. Thanks, it make sense now.
    Here is another confusion I hope you would clariy.
    In general I feel that the RevitAPI has quite a few redundant classes.
    If you want to retreive the selected elements in a document, which one of the following two statements would you use? and Why? (they both look the same to me especially that SelElementSet inherits ElementSet)
    1) ElementSet selElemSet = document.Selection.Elements
    2) SelElementSet selElemSet = document.Selection.Elements
    regards,
    Nadim

  6. Dear Nadim,
    As you say, SelElementSet inherits from ElementSet. If you need the additional functionality provided by the derived class, use it. If not, use whichever you prefer. I would personally go for the one with the shorter, simpler name, if all else is equal. If you look at the selection code I present in The Building Coder samples, especially in the region ‘Element Selection’ in the Util class, you can see what style I prefer.
    Cheers, Jeremy.

  7. Thanks. I looked again at both sets in the RevitAPI Help.chm and I can see the additional methods in the SelElementSet. Sorry about that.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading