Welcome to the second tutorial of Navisworks® API
series, this post is to cover how to Search
ModelItem
& collect ModelItem
Properties
. The task is ” to find a ModelItem
by its Id
and collect the properties data
of ModelItem
‘s Element
category. “

As usual, let’s start our project by setting up Navisworks®
Add-Ins project in the visual studio, you can follow Creating Navisworks Add-Ins
tutorial to set up the project. Whenever you are ready, in MainClass.Execute
method create two variables; Document doc
to store the current Document
and StringBuilder message
to store the display string
. (figure 1.1)

Create a simple Form
object for user input and one more variable, int Id
, to store SearchBox
return value (ModelItemId
). try-catch
statement is to handles error
of user input during the conversion to integer value. (figure 1.2)

In the SearchBox
Form
partial class, create a public property
named ReturnValue
, to store & return user input Id
value. (figure 1.3)

Back to MainClass.Execute
method, create a Search
object to runs to find ModelItem
by its Id
. There are a couple of methods in SearchCondition
class, here we uses SearchCondition.HasPropertyByDisplayName
method which create a condition that matches if item has category with specified DisplayName
(figure 1.4). Additionally, to understand better, you can uses the InternalName
or CombineName
too. In figure 1.4a, show SearchCondition.HasPropertyByName
method by InternalName
.


Let’s take one more step for solid understanding, in the figure 1.5, as you can see the relation of Navisworks® Find Items
user interface and our Search
object code.

After we found the ModelItem
via Search
, the next step is to collect a specific Category
of the ModelItem
‘s properties data. First, select this ModelItem
by using doc.CurrentSelection.Add
method. Next, to find ModelItem
‘s Element
PropertyCategory
object by using FindCategoryByDisplayName
method. From PropertyCategory
object, we can collect DataPropertyCollection
which includes all the properties data of a specific Category
, in this case, Element Category
. Add total number of properties to message
as the first line of code to display. (figure 1.6)

Iterate the properties, fetch property’s DisplayName
& Value
from the DataProperty
and add to the message
. And finally, display the message
via WindowForms'
s MessageBox
and mandatory return an int
value.
That’s the end of our tutorial, the Execute
method code is below & you can download the complete project source code from here. Cheers!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using wf = System.Windows.Forms;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
using Autodesk.Navisworks.Api.DocumentParts;
namespace Lab5_Exercise
{
[PluginAttribute("Lab5_Exec", "TwentyTwo",DisplayName = "Lab5_Exec", ToolTip = "Lab5_exercise project")]
public class MainClass : AddInPlugin
{
// implement execute method
public override int Execute(params string[] parameters)
{
// current document
Document doc = Application.ActiveDocument;
// display message
StringBuilder message = new StringBuilder();
// SearchBox form
SearchBox sb = new SearchBox();
// show form
sb.ShowDialog();
// assign Id value
int Id = 0;
try
{
// convert sb return value string to int
Id = Convert.ToInt32(sb.ReturnValue);
}
catch { }
// create search object
Search search = new Search();
// selection to search
search.Selection.SelectAll();
// create SearchCondition by InternalName of Category & Property
// to find the specific item by its ID
SearchCondition condition = SearchCondition.HasPropertyByName("LcRevitData_Element",
"LcRevitPropertyElementId").EqualValue(new VariantData(Id));
/*
// create SearchCondition by DisplayName of Category & Property
// to find the specific item by its ID
SearchCondition condition = SearchCondition.HasPropertyByDisplayName("Element",
"Id").EqualValue(new VariantData(Id));
*/
// SearchCondition to applied during search
search.SearchConditions.Add(condition);
// collect model item (if found)
ModelItem item = search.FindFirst(doc,false);
// item found
if (item != null)
{
// make selection
doc.CurrentSelection.Add(item);
// get modelitem's Element category by display name method
PropertyCategory elementCategory = item.PropertyCategories.
FindCategoryByDisplayName("Element");
// all properties of Element category
DataPropertyCollection dataProperties = elementCategory.Properties;
// display properties count
message.Append(String.Format("[{0}] ModelItem's Element Category has {1} Properties.\n",
Id.ToString(), dataProperties.Count));
// index
int index = 1;
// iterate properties
foreach (DataProperty dp in elementCategory.Properties)
{
// append to display "Property Display Name & Property Value(includes DataType)"
message.Append(String.Format("{0}. {1} => {2}\n", index, dp.DisplayName, dp.Value));
// index increment
index += 1;
}
// display message
wf.MessageBox.Show(message.ToString(), "Element Category");
}
// return value
return 0;
}
}
}
Thank you for these great tutorials! FYI I am having trouble recognizing SearchBox. Where is the reference for this?
LikeLike
Hi Xero, thanks. SearchBox is a custom winform that was just created for user input.
LikeLike
Disregard my question. Somehow I skipped an entire section in the tutorial.
LikeLike
Hahaha … 👍
LikeLike
Hi,
thanks for these tutorials!
Is there way you can search and select multiple elements by ID? (how to put that in code?)
Is there a way you can look for elements by a parameter different thant ID (like name or Revit Parameter?)
LikeLike
Hi Camne, thank a lot for your donation. I haven’t seen any method for searching multi IDs but may be you can take a look at these for search conditions sample: https://apidocs.co/apps/navisworks/2018/T_Autodesk_Navisworks_Api_SearchConditionCollection.htm
And i have a tutorial on accessing parameters : https://twentytwo.space/2020/07/18/navisworks-api-com-interface-and-adding-custom-property/
LikeLike
Hi Min.Naung, I just replace the code that selects elementid with the following code, and it always throws the “object reference not set to an instance of an object” error. I want to loop through all the objects in naviswork
//Select the all item
var all = doc.Models.CreateCollectionFromRootItems().SelectMany(m => m.DescendantsAndSelf).ToList();
var item = all[0];
// item found
LikeLike