Building Coder 链接:http://thebuildingcoder.typepad.com/blog/2010/07/change-element-type.html
Revit 二次开发论坛链接:http://revit.5d6d.com/viewthread.php?tid=1298&extra=
这是一个很简单的问题,我们也已经多次涉及,但是从没有单独列出一个主题讨论过。另外我还想借此机会深入讨论一些其它有趣的 Revit API 实验代码。
问题:
我能取得一个文档中所有的族实例。现在我想通过编程的方式改变它们的族类型。请问如何实现?
回答:
答案很简单,只要将族实例的 Symbol 属性设置为希望的族类型即可。我们在之前的两个主题中都实现过:
- Duplicating a type and assigning the new type to a family instance:
inst.Symbol = dupSym;
- Changing the symbol of a curtain panel family instance to a glazed type:
fi.Symbol = pFamilySymbol.glazed;
顺便说一下:一个族实例的类型在 Revit API 中即为元素类型(ElementType)。更复杂和完整的例程是 Lab3_4_ChangeSelectedInstanceType。除了改变
族实例的类型,这个例程还展示了其它一些实用的技巧。
Lab3_4_ChangeSelectedInstanceType 是一个基于窗体的工具,用于改变选中的标准族实例的类型。它还提供了下面的功能:
1. 获取一个族实例,或者允许用户交互地选择一个族实例;
译者注:Autodesk.Revit.UI.UIDocument.Selection.PickObject() 方法有多个重载,可以允许用户交互地选择元素。
2. 判断元素的类别;
3. 获取所有可以用于展示元素类别的族;
4. 针对每个可用族,获取其全部族类型,并用一个“族名称”到“族类型列表”的映射来维护这些信息;
5. 提供一个对话框让用户选择希望的族类型;
6. 将文档中选定元素的族类型改为新的族类型。
显然,最后一步就是你需要的答案:
inst.Symbol = form.cmbType.SelectedItem as FamilySymbol;
下面是 Lab3_4_ChangeSelectedInstanceType 的完整代码:
[Transaction( TransactionMode.Automatic )]
[Regeneration( RegenerationOption.Manual )]
public class Lab3_4_ChangeSelectedInstanceType
: IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements )
{
UIApplication app = commandData.Application;
UIDocument uidoc = app.ActiveUIDocument;
Document doc = uidoc.Document;
FamilyInstance inst =
LabUtils.GetSingleSelectedElementOrPrompt(
uidoc, typeof( FamilyInstance ) )
as FamilyInstance;
if( null == inst )
{
LabUtils.ErrorMsg(
"Selected element is not a "
+ "standard family instance." );
return Result.Cancelled;
}
// determine selected instance category:
Category instCat = inst.Category;
Dictionary<string, List<FamilySymbol>>
mapFamilyToSymbols
= new Dictionary<string, List<FamilySymbol>>();
{
WaitCursor waitCursor = new WaitCursor();
// find all corresponding families and types:
FilteredElementCollector families
= new FilteredElementCollector( doc );
families.OfClass( typeof( Family ) );
foreach( Family f in families )
{
bool categoryMatches = false;
// we cannot trust f.Category or
// f.FamilyCategory, so grab the category
// from first family symbol instead:
foreach( FamilySymbol sym in f.Symbols )
{
categoryMatches = sym.Category.Id.Equals(
instCat.Id );
break;
}
if( categoryMatches )
{
List<FamilySymbol> symbols
= new List<FamilySymbol>();
foreach( FamilySymbol sym in f.Symbols )
{
symbols.Add( sym );
}
mapFamilyToSymbols.Add( f.Name, symbols );
}
}
}
// display the form allowing the user to select
// a family and a type, and assign this type
// to the instance.
Lab3_4_Form form
= new Lab3_4_Form( mapFamilyToSymbols );
if( System.Windows.Forms.DialogResult.OK
== form.ShowDialog() )
{
inst.Symbol = form.cmbType.SelectedItem
as FamilySymbol;
LabUtils.InfoMsg(
"Successfully changed family : type to "
+ form.cmbFamily.Text + " : "
+ form.cmbType.Text );
}
return Result.Succeeded;
}
}