I have a FamilyInstance pFam
and a Autodesk.Revit.DB.View pView
. I want to know if pFam
is visible in pView
. I've tried using
if (pFam.IsHidden(pView)
continue;
Unfortunately, this only tells me if the element is supposed to be hidden, which isn't the case. But, the element is not visible in every View
, and under that circumstance, I want (or rather don't want) something to happen. There is no Visible
or IsVisible
properties for FamilyInstance
s... Does anyone know a way to handle these situations?
Thanks!
I have found that the most reliable way of knowing whether an element is visible in a view is to use a FilteredElementCollector specific to that view. There are so many different ways of controlling the visibility of an element that it would be impractical to try to determine this any other way.
Below is the utility function I use to achieve this. Note this works for any element, and not just for family instances.
public static bool IsElementVisibleInView([NotNull] this View view, [NotNull] Element el)
{
if (view == null)
{
throw new ArgumentNullException(nameof(view));
}
if (el == null)
{
throw new ArgumentNullException(nameof(el));
}
// Obtain the element's document
Document doc = el.Document;
ElementId elId = el.Id;
// Create a FilterRule that searches for an element matching the given Id
FilterRule idRule = ParameterFilterRuleFactory.CreateEqualsRule(new ElementId(BuiltInParameter.ID_PARAM), elId);
var idFilter = new ElementParameterFilter(idRule);
// Use an ElementCategoryFilter to speed up the search, as ElementParameterFilter is a slow filter
Category cat = el.Category;
var catFilter = new ElementCategoryFilter(cat.Id);
// Use the constructor of FilteredElementCollector that accepts a view id as a parameter to only search that view
// Also use the WhereElementIsNotElementType filter to eliminate element types
FilteredElementCollector collector =
new FilteredElementCollector(doc, view.Id).WhereElementIsNotElementType().WherePasses(catFilter).WherePasses(idFilter);
// If the collector contains any items, then we know that the element is visible in the given view
return collector.Any();
}
The category filter is used to eliminate any element not of the desired category before using the slower parameter filter to find the desired element. It is probably possible to speed this up further with clever usage of filters, but I have found that it is plenty fast enough for me in practice.
If you don't have ReSharper, delete the [NotNull] annotations you see.