获取与设置Assembly Parameter异常:装配体参数无法访问求助
问题描述
我编写的代码可以获取选中的FabricationPart和AssemblyInstance元素列表,但处理Assembly的参数时完全失效。相关代码如下:
获取选中元素的方法
public IList<Element> SelectElement(UIDocument uiDoc, Document doc) { List<Element> values = new List<Element>(); try { IList<Reference> reference = uiDoc.Selection.PickObjects(ObjectType.Element); foreach (Reference r in reference) { Element el = doc.GetElement(r); Category bc = doc.GetElement(r).Category; if(el is FabricationPart) { values.Add(el); } if (el is AssemblyInstance) { values.Add(el); } } } catch (Exception ex) { TaskDialog td = new TaskDialog("Selection"); td.MainContent = "No Elements Have Been Selected"; td.Show(); } return values; }
遍历元素处理参数的代码
List<Element> e = (List<Element>)SelectElement(uiDoc, doc); foreach (Element element in e) { Parameter p = element.LookupParameter("TPFullFabricationServiceName"); // 参数处理逻辑... }
针对FabricationPart可正常运行的参数处理逻辑
if (element.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString() == "Pipe" || element.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString() == "Tee" || element.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString() == "Elbow") { p.Set(element.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString()); }
部分参数绑定到FabricationPart类别,另一部分绑定到Assembly类别。请问是否需要以不同方式访问Assembly?
解决方案
是的,AssemblyInstance和FabricationPart的参数访问逻辑完全不同——AssemblyInstance是容器元素,它自身的参数与内部构件的参数相互独立,你需要明确目标是访问Assembly自身参数,还是其内部构件的参数:
1. 访问AssemblyInstance自身的参数
如果TPFullFabricationServiceName是绑定到Assembly类别的共享/项目参数,直接用LookupParameter或get_Parameter即可,但需先判断元素类型,再针对性处理:
List<Element> e = SelectElement(uiDoc, doc).ToList(); // 用ToList()替代强制转换,避免异常 foreach (Element element in e) { if (element is FabricationPart fabPart) { // 原有FabricationPart处理逻辑 Parameter p = fabPart.LookupParameter("TPFullFabricationServiceName"); string productType = fabPart.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString(); if (productType is "Pipe" or "Tee" or "Elbow") { p.Set(fabPart.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString()); } } else if (element is AssemblyInstance assembly) { // 访问Assembly自身参数 Parameter p = assembly.LookupParameter("TPFullFabricationServiceName"); if (p != null) { // 示例:从Assembly内部的FabricationPart提取服务名赋值给Assembly自身参数 foreach (ElementId memberId in assembly.GetMemberIds()) { Element member = doc.GetElement(memberId); if (member is FabricationPart fabMember) { string serviceName = fabMember.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString(); p.Set(serviceName); break; // 取第一个符合条件的构件值,可按需调整 } } } } }
2. 访问AssemblyInstance内部构件的参数
如果目标是修改Assembly内部FabricationPart的TPFullFabricationServiceName参数,需要先通过assembly.GetMemberIds()获取所有内部构件ID,再逐个处理:
else if (element is AssemblyInstance assembly) { foreach (ElementId memberId in assembly.GetMemberIds()) { Element member = doc.GetElement(memberId); if (member is FabricationPart fabMember) { Parameter p = fabMember.LookupParameter("TPFullFabricationServiceName"); string productType = fabMember.get_Parameter(BuiltInParameter.FABRICATION_PRODUCT_DATA_PRODUCT).AsString(); if (productType is "Pipe" or "Tee" or "Elbow") { p.Set(fabMember.get_Parameter(BuiltInParameter.FABRICATION_SERVICE_NAME).AsString()); } } } }
额外优化建议
- 简化
SelectElement方法的元素判断逻辑:if(el is FabricationPart || el is AssemblyInstance) { values.Add(el); } - 避免强制转换
IList<Element>为List<Element>,改用ToList()方法保证类型安全:List<Element> e = SelectElement(uiDoc, doc).ToList();
内容的提问来源于stack exchange,提问作者nhilson
相关产品推荐
相关产品推荐

