Building Coder(Revit 二次開發) - 爲一個共享參數綁定添加一個類別

原文鏈接:Adding a Category to a Shared Parameter Binding


爲一個共享參數綁定添加一個類別(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;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章