原文链接:
Adding a Category to a Shared Parameter Binding
为一个共享参数绑定添加一个类别(Adding a Category to a Shared Parameter Binding)
问题
我使用 VB.NET 遍历一个项目中的一组族,为类型添加共享参数,并使用如下的代码将为类别定义的共享参数应用到族:
(以下这段 VB.NET 代码不太复杂,相信大家都能看懂)
这段代码在处理第一个族(Furniture 类别)时挺正常的,所有的家俱族都具有了指定的共享参数。但是在处理另外一个属于不同类别(Special Equipment)的族时,虽然函数调用值都是正常的,但是共享参数并没有被绑定到新的类别。我如何才能将同一个共享参数绑定到多个族类别呢?
Jeremy
正确的做法是将需要绑定到指定共享参数的所有类别全部添加到一个 CategorySet,然后一次性地完成绑定。
问题
问题是我在第一次创建共享参数的时候,没有办法知道所有需要绑定的类别。而且需要绑定的类别会一直变化。我的 Add-in 会定时从一个外部数据源读取数据,然后实时地创建并更新相关的(共享)参数值。
Revit API 是否允许我获取当前绑定到指定共享参数的类别集合,添加新的类别,然后再重新创建绑定?还是说绑定只能在第一次创建时完成?
Jeremy
你可以在绑定完成之后再添加新的类别。以下是实现你的需求的代码:
为一个共享参数绑定添加一个类别(Adding a Category to a Shared Parameter Binding)
问题
我使用 VB.NET 遍历一个项目中的一组族,为类型添加共享参数,并使用如下的代码将为类别定义的共享参数应用到族:
(以下这段 VB.NET 代码不太复杂,相信大家都能看懂)
'create a category set with the Element category in it
Dim categories As Autodesk.Revit.DB.CategorySet
categories = app.Create.NewCategorySet
Dim LCategory As Autodesk.Revit.DB.Category
LCategory = doc.Settings.Categories.Item( iCategory.Name.ToString)
categories.Insert(LCategory)
'create a new Type binding for the Symbol categories
Dim TypeBinding As Autodesk.Revit.DB.TypeBinding
TypeBinding = app.Create.NewTypeBinding(categories)
'Bind the parameter
doc.ParameterBindings.Insert( sharedParameterDefinition, TypeBinding)
这段代码在处理第一个族(Furniture 类别)时挺正常的,所有的家俱族都具有了指定的共享参数。但是在处理另外一个属于不同类别(Special Equipment)的族时,虽然函数调用值都是正常的,但是共享参数并没有被绑定到新的类别。我如何才能将同一个共享参数绑定到多个族类别呢?
Jeremy
正确的做法是将需要绑定到指定共享参数的所有类别全部添加到一个 CategorySet,然后一次性地完成绑定。
问题
问题是我在第一次创建共享参数的时候,没有办法知道所有需要绑定的类别。而且需要绑定的类别会一直变化。我的 Add-in 会定时从一个外部数据源读取数据,然后实时地创建并更新相关的(共享)参数值。
Revit API 是否允许我获取当前绑定到指定共享参数的类别集合,添加新的类别,然后再重新创建绑定?还是说绑定只能在第一次创建时完成?
Jeremy
你可以在绑定完成之后再添加新的类别。以下是实现你的需求的代码:
public static BindSharedParamResult BindSharedParam(
Document doc,
Category cat,
string paramName,
string grpName,
ParameterType paramType,
bool visible,
bool instanceBinding )
{
try
{
Application app = doc.Application;
// 与指定共享参数绑定的类别集合(完成绑定之后再次添加新的类别就需要调用 ReInsert 方法)
CategorySet catSet = app.Create.NewCategorySet();
// 遍历所有的绑定定义
DefinitionBindingMapIterator iter = doc.ParameterBindings.ForwardIterator();
while( iter.MoveNext() )
{
Definition def = iter.Key;
ElementBinding elemBind = (ElementBinding) iter.Current;
// 判断指定的共享参数是否已经被绑定了
if( paramName.Equals( def.Name, StringComparison.CurrentCultureIgnoreCase ) )
{
// 判断指定的类别是否已经绑定了指定的共享参数(注意:elemBind.Categories.Size 值始终为 1)
if( elemBind.Categories.Contains( cat ) )
{
// 判断绑定的共享参数的类型与指定的共享参数类型是否相同
if( paramType != def.ParameterType )
{
return BindSharedParamResult.eWrongParamType;
}
// 判断绑定模型与指定的绑定模式是否相同
if( instanceBinding )
{
if( elemBind.GetType() != typeof( InstanceBinding ) )
{
return BindSharedParamResult.eWrongBindingType;
}
}
else
{
if( elemBind.GetType() != typeof( TypeBinding ) )
{
return BindSharedParamResult.eWrongBindingType;
}
}
// 判断共享参数的可见性
// ......
return BindSharedParamResult.eAlreadyBound;
}
// 指定的类别还没有和指定的共享参数绑定
else
{
foreach( Category catOld in elemBind.Categories )
{
catSet.Insert( catOld ); // 1 only, but no index...
}
}
}
}
DefinitionFile defFile = GetOrCreateSharedParamsFile( app );
DefinitionGroup defGrp = GetOrCreateSharedParamsGroup( defFile, grpName );
Definition definition = GetOrCreateSharedParamDefinition( defGrp, paramType, paramName, visible );
catSet.Insert( cat );
InstanceBinding bind = null;
if( instanceBinding )
{
bind = app.Create.NewInstanceBinding( catSet );
}
else
{
bind = app.Create.NewTypeBinding( catSet );
}
// 以下是 Revit API 设计的不太直观的地方:如果绑定已经存在,则需要调用 ReInsert 绑定更新后的定义。
// 请参考我之前的一篇博文:http://thebuildingcoder.typepad.com/blog/2009/09/adding-a-category-to-a-parameter-binding.html
if( doc.ParameterBindings.Insert( definition, bind ) )
{
return BindSharedParamResult.eSuccessfullyBound;
}
else
{
if( doc.ParameterBindings.ReInsert( definition, bind ) )
{
return BindSharedParamResult.eSuccessfullyBound;
}
else
{
return BindSharedParamResult.eFailed;
}
}
}
catch( Exception ex )
{
MessageBox.Show( string.Format( "Error in Binding Shared Param: {0}", ex.Message ) );
return BindSharedParamResult.eFailed;
}
}