Family Instance Missing Level Property

Here is another contribution by Rudolf Honke of acadGraph CADstudio GmbH. He says:

"And now for something completely different" ... after all the UI Automation topics:

I often need to collect all items on a specific level, for instance window family instances, and use a method like the following to do so:

List<Element> GetWindowsByLevel( 
  Document doc, 
  Level level )
{
  List<Element> elementList = new List<Element>();
 
  FilteredElementCollector collector 
    = new FilteredElementCollector( doc )
      .OfCategory( BuiltInCategory.OST_Windows );
 
  ParameterValueProvider provider 
    = new ParameterValueProvider( 
      new ElementId( 
        BuiltInParameter.FAMILY_LEVEL_PARAM ) );
 
  FilterNumericRuleEvaluator evaluator 
    = new FilterNumericEquals();
 
  ElementId idRuleValue = level.Id;
 
  FilterElementIdRule rule 
    = new FilterElementIdRule( 
      provider, evaluator, idRuleValue );
 
  ElementParameterFilter filter 
    = new ElementParameterFilter( rule );
 
  elementList.AddRange( 
    collector.WherePasses( filter ).ToElements() );
 
  return elementList;
}

Strangely enough, it may occur that some elements are not found by this method, because their level property has not been correctly set.

Here are the element properties of a window with its level property (Ebene in German) properly set:

Window with Level property properly set

Other window instances, however, may be lacking this property:

Window with Level property missing

If we take a look at the second window instance parameters using the RevitLookup 'snoop built-in enums' functionality, we see that it has no FAMILY_LEVEL_PARAM parameter:

Window lacking FAMILY_LEVEL_PARAM parameter

This window instance also has a null value for its Level property:

Window has null Level property

Sometimes, you can set a parameter to affect a property. Similarly, you can move or rotate an element to change its location point or curve.

Sometimes a property and the parameter that should relate to this property are inconsistent with each other, but that's another point.

In the element property page, you cannot set the property, because it is not displayed there at all.

Therefore, this is one of the rare occasions where you can achieve something via the API that cannot be done through the user interface.

In this case, you can use this little workaround:

Level selector
  windowWithoutLevelParam.get_Parameter( 
    BuiltInParameter.FAMILY_LEVEL_PARAM )
    .Set( levels[levelDialogSelectedIndex].Id );

Once assigned programmatically, the level property also becomes visible to the user:

Window Level property displayed

After this adjustment, the GetWindowsByLevel method returns the results it is designed for as expected.

Many thanks to Rudolf for this detailed analysis and workaround!