Building Coder 链接:http://thebuildingcoder.typepad.com/blog/2011/01/family-instance-missing-level-property.html
Revit二次开发论坛链接:http://revit.5d6d.com/viewthread.php?tid=1280&page=1&extra=#pid1782
这个主题由acadGraph CADstudio GmbH(http://www.acadgraph.de/)的Rudolf Honke提供。
有时候我们会需要取得位于指定层的所有元素,比方说窗族的所有实例。下面我使用的一个辅助函数:
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;
}
但是很奇怪,这样做有时候会遗漏一些元素。问题出在这些元素的层属性没有被正确设置。这一点可以通过打开元素的属性视图来验证。对于那些没有设置层属性的元素,你无法在其属性窗口中找到“层”这一项。进一步使用 RevitLookup 的”snoop built-in enums” 命令,你会发现原来是这些族实例的原生参数集合中不存在FAMILY_LEVEL_PARAM 参数,或是虽然存在但是值为null 。
有时候我们可以通过设置一个参数来影响一个属性。比方说通过移动或者旋转一个元素来改变它的位置和曲线。另外一些情况下,属性和那些“应该”与其相关的参数之间实际上没有关联。不过这是另外一个话题了。
回到我们讨论的问题上。由于层属性没有出现在属性视图中,所以我们无法手工设置它的值。这样一个罕见的情况出现了:我们只能通过调用Revit API 编程的方式解决这个问题。而无法通过Revit 操作的方式解决。(译者注:绝大多数情况下,通过Revit API 实现的功能是通过Revit 操作实现的功能的子集。但是显然,这个主题讨论的是一个特例)
现在让我们来看看利用Revit API 解决这个问题的具体步骤:
1. 首先获取当前文档中所有层;
2. 提供一个合适的GUI 方式让用户选择目标层;
3. 使用如下代码为缺少层属性的族实例设置层属性。
windowWithoutLevelParam.
get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM).
Set(levels[levelDialogSelectedIndex].Id);
为所有缺少层属性的族实例执行以上操作。然后 GetWindowsByLevel() 方法就可以正常工作了。