参数

Revit提供了一种常规机制,为每个图元提供一组可编辑的参数。

在Revit UI中,某些图元参数在“图元属性”窗口中可见。以下各节介绍如何获取和使用内置参数、共享参数和全局参数。

在Revit Platform API中,参数在Element类中进行管理。您可以通过以下方式访问参数:

  • 通过迭代元素的所有参数的Element.Parameters集合(有关示例,请参见获取选定元素参数演练中的示例代码)。
  • 通过迭代Element.GetOrderedParameters()返回的集合,该集合仅返回属性选项板中可见的参数。
  • 通过重载的Element.Parameter属性直接访问参数。如果参数不存在,则属性返回null。
  • 通过Element.ParametersMap集合按名称访问参数。
  • 按名称字符串Element.LookupParameter()或Element.GetParameters()。

如果知道内置ID、定义或参数,则可以使用重载的Parameter属性从Element中检索Parameter对象。Parameter[NULL]属性重载根据其全局唯一ID(Global Unique ID,NULL)获取共享参数,该全局唯一ID在创建共享参数时分配给该共享参数。}]}

Element.LookupParameter()方法根据参数的本地化名称获取参数,因此如果要按名称查找参数并且需要在多个区域设置中运行,则代码应处理不同的语言。此外,请记住,可能会出现同名参数的多个匹配,因为即使已经存在同名的内置参数,共享参数或项目参数也可以绑定到元素类别。因此,最好使用Element. GetParameter(),它将返回与给定名称匹配的所有参数。LookupParameter()将返回找到的第一个匹配项。

本节中的页面

  • 演练:获取选定的元素参数
  • 参数关系
  • 定义
  • 内置参数
  • 共享参数
  • 全局参数
  • 参数

演练:获取选定的元素参数

元素参数是通过遍历元素参数集来检索的。下面的代码示例阐释如何从选定的元素中检索Parameter。

****注意:****此示例使用了一些参数成员,如AsValueString和DataType,这些将在后续主题中介绍。

代码区域8-1:获取选定的元素参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
void GetElementParameterInformation(Document document, Element element)
{
// Format the prompt information string
String prompt = "Show parameters in selected Element: \n\r";

StringBuilder st = new StringBuilder();
// iterate element's parameters
foreach (Parameter para in element.Parameters)
{
st.AppendLine(GetParameterInformation(para, document));
}

// Give the user some information
TaskDialog.Show("Revit", prompt + st.ToString());
}

String GetParameterInformation(Parameter para, Document document)
{
string defName = para.Definition.Name + "\t : ";
string defValue = string.Empty;
// Use different method to get parameter data according to the storage type
switch (para.StorageType)
{
case StorageType.Double:
//covert the number into Metric
defValue = para.AsValueString();
break;
case StorageType.ElementId:
//find out the name of the element
Autodesk.Revit.DB.ElementId id = para.AsElementId();
if (id.IntegerValue >= 0)
{
defValue = document.GetElement(id).Name;
}
else
{
defValue = id.IntegerValue.ToString();
}
break;
case StorageType.Integer:
if (ParameterType.YesNo == para.Definition.ParameterType)
{
if (para.AsInteger() == 0)
{
defValue = "False";
}
else
{
defValue = "True";
}
}
else
{
defValue = para.AsInteger().ToString();
}
break;
case StorageType.String:
defValue = para.AsString();
break;
default:
defValue = "Unexposed parameter.";
break;
}

return defName + defValue;
}

图26:获取墙参数结果

注意:在Revit中,某些参数的值位于“图元属性”对话框的下拉列表中。可以使用Revit Platform API获取与Parameter的枚举类型对应的数值,但不能使用Parameter.AsValueString()方法获取值的字符串表示形式。

参数关系

参数可以相互影响。

参数之间存在关系,其中一个参数的值可以影响:

  • 是否可以设置另一个参数,或者是否为只读
  • 哪些参数对元素有效
  • 另一个参数的计算值

此外,某些参数始终是只读的。

某些参数在Revit中计算,例如墙长度和面积参数。这些参数总是只读的,因为它们依赖于元素的内部状态。

在此代码示例中,洞口的“Sill Height”参数将被调整,从而导致重新计算“Head Height”参数:

代码区域:参数关系示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// opening should be an opening such as a window or a door
public void ShowParameterRelationship(FamilyInstance opening)
{
// get the original Sill Height and Head Height parameters for the opening
Parameter sillPara = opening.get_Parameter(BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM);
Parameter headPara = opening.get_Parameter(BuiltInParameter.INSTANCE_HEAD_HEIGHT_PARAM);
double sillHeight = sillPara.AsDouble();
double origHeadHeight = headPara.AsDouble();

// Change the Sill Height only and notice that Head Height is recalculated
sillPara.Set(sillHeight + 2.0);
double newHeadHeight = headPara.AsDouble();
MessageBox.Show("Old head height: " + origHeadHeight + "; new head height: "
+ newHeadHeight);
}

全局参数也与其他参数有关系。有关详细信息,请参见“全局参数基础”主题。

定义

定义对象描述数据类型、名称和其他参数细节。

有两种类型的定义对象派生自该对象。

  • InternalDefinition表示完全存在于Revit数据库中的所有类型的定义。
  • ExternalDefinition表示存储在磁盘上的共享参数文件中的定义。

您应该编写使用Definition基类的代码,以便该代码适用于内部和外部参数定义。下面的代码示例演示如何使用定义类型查找特定参数。

代码区域8-2:根据定义类型查找参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Find parameter using the Parameter's definition type.
public Parameter FindParameter(Element element)
{
Parameter foundParameter = null;
// This will find the first parameter that measures length
foreach (Parameter parameter in element.Parameters)
{
if (parameter.Definition.ParameterType == ParameterType.Length)
{
foundParameter = parameter;
break;
}
}
return foundParameter;
}

参数类型

此属性返回参数数据类型,这会影响参数在Revit UI中的显示方式。一些参数类型枚举成员包括:

Member name 成员名称 Description 描述
Number 参数数据应解释为真实的数字,可能包括小数点。
Moment 数据值将表示为力矩。
AreaForce 数据值将表示为面积力。
LinearForce 数据值将表示为线性力。
Force 数据值将表示为力。
YesNo 一个布尔值,表示为Yes或No。
Material 此属性的值被视为材料。
URL 表示网址的文本字符串。
Angle 参数数据表示角度。内部表示将以弧度表示。用户可见表示将使用用户选择的单位。
Volume 参数数据表示体积。内部表示将以十进制立方英尺为单位。用户可见表示将使用用户选择的单位。
Area 参数数据表示一个区域。内部表示将以十进制平方英尺为单位。用户可见表示将使用用户选择的单位。
Integer 参数数据应解释为整数,正数或负数。
Invalid 参数类型无效。不应使用此值。
Length 参数数据表示长度。内部表示将以十进制英尺为单位。用户可见表示将在用户选择的单位系统中。
Text 参数数据应解释为文本字符串。
MultilineText 此参数的值将表示为多行文本。
FamilyType 用于控制嵌套在另一个族中的族的类型的参数。
Image 该参数的值是图像的id。

有关参数类型.材质的更多详细信息,请参见材质。

ParameterGroup 参数组

定义类参数组属性返回参数定义组ID。BuiltInParameterGroup是一种枚举类型,列出了Revit支持的所有内置参数组。参数组用于对“图元属性”对话框中的参数进行排序。

内部定义

每个Parameter对象都有一个InternalDefinition,它可以从Definition属性中获得。InternalDefinition表示Revit文档中的参数定义。除了从Definition继承的属性之外,它还具有一些其他关键属性。

BuiltInParameter 内置参数

此属性测试此定义是否标识内置参数。对于内置参数,此属性返回BuiltInParameter枚举值之一。对于自定义参数(如共享参数、全局参数或族参数),该值将为BuiltInParameter.INVALID。

Id

如果参数不是内置的,则此属性返回关联的ParameterElement的ID。

VariesAcrossGroups

该属性和相应的SetAllowVaryBetweenGroups()方法确定该参数的值是否可以在组实例的相关成员之间变化。如果为False,则组实例中相关成员的值将保持一致。这只能为非内置参数设置。

Visible 可见

visible属性指示是否对用户隐藏共享参数。如果您希望将数据添加到仅对您的应用程序有意义而对用户没有意义的元素中,这将非常有用。此值只能在创建共享参数定义时设置。

内置参数

Revit Platform API具有大量内置参数。

内置参数在Autodesk.Revit.Parameters.BuiltInParameter枚举中定义(有关此枚举的定义,请参见RevitAPI Help.chm文件)。此枚举已生成可从Visual Studio intellisense看到的文档,如下所示。每个id的文档都包括参数名称,如Autodesk Revit英文版的“图元属性”对话框中所示。请注意,多个不同的参数id可能映射到同一个英文名称;在这种情况下,您必须检查与特定元素关联的参数,以确定使用哪个参数id。

参数ID用于从元素中检索特定参数,如果它存在,使用Element.Parameter属性。但是,并非所有参数都可以使用ID进行检索。例如,族参数未在Revit Platform API中显示,因此,您无法使用内置参数ID获取它们。

以下代码示例显示如何使用BuiltInParameter Id获取特定参数:

代码区域8-3:基于BuiltInParameter获取参数

1
2
3
4
5
6
7
8
9
public Parameter FindWithBuiltinParameterID(Wall wall)
{
// Use the WALL_BASE_OFFSET paramametId
// to get the base offset parameter of the wall.
BuiltInParameter paraIndex = BuiltInParameter.WALL_BASE_OFFSET;
Parameter parameter = wall.get_Parameter(paraIndex);

return parameter;
}

注意:通过Parameter重载,可以使用枚举类型BuiltInParameter作为方法参数.例如,使用BuiltInParameter.GENERIC_WIDTH。

如果不知道确切的BuiltInParameter ID,请通过迭代ParameterSet集合获取参数。另一种用于测试或识别目的的方法是使用get_Parameter()方法测试每个BuiltInParameter。当您使用此方法时,参数集集合可能不包含从get_Parameter()方法返回的所有参数,尽管这种情况并不常见。

共享参数

共享参数是存储在外部文本文件中的参数定义。

定义由创建定义时生成的唯一标识符标识,并且可以在多个项目中使用。

与共享参数关联的主要对象有:

  • DefinitionFile -表示磁盘上的共享参数文件
  • DefinitionGroup -一组共享参数,它们被组织成有意义的集合
  • ExternalDefinition -表示一个共享参数定义,属于一个配置组
  • ExternalDefinitions -支持创建新的共享参数定义
  • Binding-将参数定义绑定到一个或多个类别
  • BindingMap -包含Autodesk Revit项目中存在的所有参数绑定
  • ParameterElement-存储有关文档中特定用户定义参数的信息
  • SharedParameterElement -从ParameterElement派生,存储共享参数的定义以下各节介绍如何通过Revit Platform API访问共享参数定义,包括如何获取共享参数定义并将其绑定到某些类别中的元素。

要在定义共享参数并将其绑定到类别后访问共享参数,请参见参数。

本节中的页面

  • Definition File
  • Working with the Definition File
  • Binding
  • SharedParameterElement

Definition File

DefinitionFile 表示一个共享参数文件,它是一个通用文本文件。

Format 格式

共享参数定义文件是一个文本文件(.txt),包含三个块:Meta、GROUP和PARAM。GROUP和PARAM块与Revit API中的共享参数功能相关。不要直接编辑定义文件;而是使用UI或API编辑它。

尽管Revit API负责阅读和写入此文件,但以下部分提供了文件格式的信息,该文件格式与用于访问共享参数的API对象和方法密切对应。该文件使用制表符分隔字段,在文本编辑器中很难阅读。下面的代码区域显示了示例共享参数文本文件的内容。

代码区域22-1:参数定义文件示例

1
2
3
4
5
6
7
8
9
10
11
# This is a Revit shared parameter file.
# Do not edit manually.
META VERSION MINVERSION
META 2 1
GROUP ID NAME
GROUP 1 MyGroup
GROUP 2 AnotherGroup
*PARAM GUID NAME DATATYPE DATACATEGORY GROUP VISIBLE DESCRIPTION USERMODIFIABLE
PARAM bb7f0005-9692-4b76-8fa3-30cec8aecf74 Price INTEGER 2 1 Enter price in USD 1
PARAM b7ea2654-b206-4694-a087-756359b52e7f areaTags FAMILYTYPE -2005020 1 1 1
PARAM d1a5439d-dc8d-4053-99fa-2f33804bae0e MyParam TEXT 1 1 1
  • GROUP块包含将每个参数定义与组关联的组条目。以下字段显示在GROUP块中:

    • ID -唯一标识组并将参数定义与组关联。
    • Name - UI中显示的组名称。
  • PARAM块包含参数定义。以下字段出现在PARAM块中:

    • GUID - 识别参数定义。

    • NAME - 参数定义名称。

    • DATATYPE -参数类型。此字段可以是常见类型(TEXT、INTEGER等),结构类型(力、力矩等)或常用族类型(面积标记等)。通用类型和结构类型参数直接在文本文件中指定(例如:文本,力)。如果DATATYPE字段的值为FAMILYTYPE,则添加一个额外的数字。例如,FAMILYTYPE后跟-2005020表示族类型:面积标记。

    • DATACATEGORY -DATATYPE为FAMILYTYPE的参数的可选字段。

    • GROUP -用于标识包含当前参数定义的组的组ID。

    • VISIBLE -确定参数是否可见。此字段的值为0或1.0

    • DESCRIPTION - 此参数的工具提示的可选字段。

    • USERMODIFIABLE -确定参数是否可由用户编辑。0 =用户无法编辑参数,并且该参数在UI中呈灰色显示

在示例定义文件中,有两个组:

  • MyGroup - ID 1 -包含MyParam的参数定义(文本类型参数)和areaTags的定义(家庭类型参数)。
  • AnotherGroup - ID 2 -包含Price的参数定义,它是一个价格类型参数。

Of the 3 parameters in the sample file, only Price has a description. All of the parameters are visible and user modifiable.
在示例文件中的3个参数中,只有Price有描述。所有的参数都是可见的,用户可以修改。

Working with the Definition File

定在定义文件中设置参数义文件提供对共享参数的访问。

在定义文件中设置参数

使用以下步骤访问定义文件及其参数:

  1. 使用现有文本文件或新文本文件指定Application.SharedParametersFiltrate属性。
  2. 使用Application.OpenSharedParameterFile()方法打开共享参数文件。
  3. 打开一个现有组或使用configtionFile.groups属性创建一个新组。
  4. 打开现有的外部参数定义或使用configuretionGroup.Definitions属性创建新定义。

Autodesk. Revit. DB命名空间中的以下类和方法提供了使用Revit API访问共享参数的功能。

  • DefinitionFile 类
    • 使用Application.OpenSharedParameterFile()方法检索。Revit每次使用一个共享参数文件。
    • 表示一个共享参数文件。
    • 包含多个Group对象。
    • 共享参数被分组以便于管理,并包含共享参数定义。
    • 可以根据需要添加新的定义。
  • ExternalDefinition 类
    • ExternalDefinition对象是由一个共享参数文件中的ExternationGroup对象创建的。
    • 外部参数定义必须属于一个组,该组是共享参数定义的集合。
  • Application.SharedParametersFilename 属性
    • 使用此属性获取和设置共享参数文件路径。
    • 默认情况下,Revit没有共享参数文件。
    • 使用前初始化此属性。如果它没有初始化,则会引发异常。

创建共享参数文件

代码区域22-3:创建共享参数文件

1
2
3
4
5
private void CreateExternalSharedParamFile(string sharedParameterFile)
{
System.IO.FileStream fileStream = System.IO.File.Create(sharedParameterFile);
fileStream.Close();
}

访问现有共享参数文件

由于Revit可以有许多共享参数文件,因此必须明确标识要访问的文件和外部参数。以下两个过程说明如何访问现有的共享参数文件。

从外部参数文件中获取配置文件

按照下面的代码所示设置共享参数文件路径,然后调用Application.OpenSharedParameterFile()方法。

代码区域22-4:从外部参数文件获取定义文件

1
2
3
4
5
6
7
private DefinitionFile SetAndOpenExternalSharedParamFile(Autodesk.Revit.ApplicationServices.Application application, string sharedParameterFile)
{
// set the path of shared parameter file to current Revit
application.SharedParametersFilename = sharedParameterFile;
// open the file
return application.OpenSharedParameterFile();
}

注:设置共享参数路径时,请考虑以下几点: 在每次安装过程中,Revit无法检测是否在其他版本中设置了共享参数文件。必须再次为新的Revit安装绑定共享参数文件。 如果Application. SharedParametersFilm设置为无效路径,则仅在调用OpenSharedParameterFile()时引发异常。 * Revit可以使用多个共享参数文件。即使加载参数时只使用一个参数文件,也可以自由更改当前文件。

遍历所有参数

下面的示例阐释如何遍历参数项并在消息框中显示结果。

代码区域22-5:遍历参数条目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void ShowDefinitionFileInfo(DefinitionFile myDefinitionFile)
{
StringBuilder fileInformation = new StringBuilder(500);

// get the file name
fileInformation.AppendLine("File Name: " + myDefinitionFile.Filename);

// iterate the Definition groups of this file
foreach (DefinitionGroup myGroup in myDefinitionFile.Groups)
{
// get the group name
fileInformation.AppendLine("Group Name: " + myGroup.Name);

// iterate the difinitions
foreach (Definition definition in myGroup.Definitions)
{
// get definition name
fileInformation.AppendLine("Definition Name: " + definition.Name);
}
}
TaskDialog.Show("Revit",fileInformation.ToString());
}

更改参数定义所有者组

以下示例说明如何更改参数定义组所有者。

代码区域22-6:更改参数定义组所有者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void ReadEditExternalParam(DefinitionFile file)
{
// get ExternalDefinition from shared parameter file
DefinitionGroups myGroups = file.Groups;
DefinitionGroup myGroup = myGroups.get_Item("MyGroup");
if (myGroup != null)
{
ExternalDefinition myExtDef = myGroup.Definitions.get_Item("MyParam") as ExternalDefinition;
if (myExtDef != null)
{
DefinitionGroup newGroup = myGroups.get_Item("AnotherGroup");
if (newGroup != null)
{
// change the OwnerGroup of the ExternalDefinition
myExtDef.OwnerGroup = newGroup;
}
}
}
}

Binding

绑定是将共享参数与模型中某些类别的元素联系在一起。

有两种类型的绑定可用,实例绑定和类型绑定。两者之间的主要区别在于,实例绑定参数出现在这些类别中元素的所有实例上。更改其中一个实例的参数不会影响该参数的其他实例。类型绑定参数仅出现在类型对象上,并由使用该类型的所有实例共享。更改类型绑定参数会影响使用该类型的元素的所有实例。请注意,定义只能绑定到实例或类型,而不能同时绑定到两者。

要绑定参数,请执行以下操作:

  1. 使用InstanceBinding或TypeBinding对象可以创建一个新的Binding对象,该对象包括参数绑定到的类别。
  2. 使用Document.ParameterBindings属性提供的BindingMap对象将绑定和定义添加到文档中。

Autodesk.Revit.DB命名空间中的以下类和方法提供了有关将参数绑定到元素的详细信息。

  • BindingMap类
    • 从Document.ParameterBindings属性检索。
    • 参数绑定将参数定义连接到一个或多个类别中的元素。
    • 该映射用于查询现有绑定以及使用Insert方法生成新的参数绑定。
  • BindingMap.Insert()方法
    • 绑定对象类型规定参数是绑定到所有实例还是仅绑定到类型。
    • 参数定义不能同时绑定到实例和类型。
    • 如果参数绑定存在,则该方法返回false。

Type Binding

TypeBinding对象用于将特性绑定到Revit类型(如墙类型)。它与实例绑定的不同之处在于,该属性由类型绑定中标识的所有实例共享。更改一个类型的参数会影响同一类型的所有实例。

下面的代码示例演示如何使用共享参数文件添加参数定义。以下代码执行的操作与使用Revit UI中的对话框执行的操作相同。参数定义按以下顺序创建:

  1. 将创建共享参数文件。
  2. 将为墙类型创建定义组和参数定义。
  3. 定义将根据墙类别绑定到当前文档中的墙类型参数。

代码区域22-7:使用共享参数文件添加类型参数定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public bool SetNewParameterToTypeWall(UIApplication app, DefinitionFile myDefinitionFile)
{
// Create a new group in the shared parameters file
DefinitionGroups myGroups = myDefinitionFile.Groups;
DefinitionGroup myGroup = myGroups.Create("MyParameters");

// Create a type definition
ExternalDefinitionCreationOptions option = new ExternalDefinitionCreationOptions("CompanyName", ParameterType.Text);
Definition myDefinition_CompanyName = myGroup.Definitions.Create(option);

// Create a category set and insert category of wall to it
CategorySet myCategories = app.Application.Create.NewCategorySet();
// Use BuiltInCategory to get category of wall
Category myCategory = Category.GetCategory(app.ActiveUIDocument.Document, BuiltInCategory.OST_Walls);

myCategories.Insert(myCategory);

//Create an object of TypeBinding according to the Categories
TypeBinding typeBinding = app.Application.Create.NewTypeBinding(myCategories);

// Get the BingdingMap of current document.
BindingMap bindingMap = app.ActiveUIDocument.Document.ParameterBindings;

// Bind the definitions to the document
bool typeBindOK = bindingMap.Insert(myDefinition_CompanyName, typeBinding,
BuiltInParameterGroup.PG_TEXT);
return typeBindOK;
}

Instance Binding

InstanceBinding对象指示参数定义和某些类别实例中的参数之间的绑定。

Once bound, the parameter appears in all property dialog boxes for the instance (if the visible property is set to true). Changing the parameter in any one instance does not change the value in any other instance.
绑定后,该参数将显示在实例的所有属性对话框中(如果visible属性设置为true)。在任何一个实例中更改参数不会更改任何其他实例中的值。

The following code sample demonstrates how to add parameter definitions using a shared parameter file. Parameter definitions are added in the following order:
下面的代码示例演示如何使用共享参数文件添加参数定义。参数定义按以下顺序添加:

  1. A shared parameter file is created
    创建共享参数文件
  2. A definition group and a definition for all Walls instances is created
    将创建所有墙实例的定义组和定义
  3. Definitions are bound to each wall instance parameter in the current document based on the wall category.
    定义将根据墙类别绑定到当前文档中的每个墙实例参数。

代码区域22-8:使用共享参数文件添加实例参数定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public bool SetNewParameterToInstanceWall(UIApplication app, DefinitionFile myDefinitionFile)
{
// create a new group in the shared parameters file
DefinitionGroups myGroups = myDefinitionFile.Groups;
DefinitionGroup myGroup = myGroups.Create("MyParameters1");

// create an instance definition in definition group MyParameters
ExternalDefinitonCreationOptions option = new ExternalDefinitonCreationOptions("Instance_ProductDate", ParameterType.Text);
// Don't let the user modify the value, only the API
option.UserModifiable = false;
// Set tooltip
option.Description = "Wall product date";
Definition myDefinition_ProductDate = myGroup.Definitions.Create(option);

// create a category set and insert category of wall to it
CategorySet myCategories = app.Application.Create.NewCategorySet();
// use BuiltInCategory to get category of wall
Category myCategory = Category.GetCategory(app.ActiveUIDocument.Document, BuiltInCategory.OST_Walls);

myCategories.Insert(myCategory);

//Create an instance of InstanceBinding
InstanceBinding instanceBinding = app.Application.Create.NewInstanceBinding(myCategories);

// Get the BingdingMap of current document.
BindingMap bindingMap = app.ActiveUIDocument.Document.ParameterBindings;

// Bind the definitions to the document
bool instanceBindOK = bindingMap.Insert(myDefinition_ProductDate,
instanceBinding, BuiltInParameterGroup.PG_TEXT);
return instanceBindOK;
}

SharedParameterElement

SharedParameterElements存储有关文档中特定用户定义的共享参数的信息

用户定义的参数存储在文档中,并由ParameterElement类表示。子类SharedParameterElement表示加载到文档中的共享参数。ParemeterElement也是GlobalParameter的基类。

一旦共享参数被加载到文档中,就可以从SharedParameterElement类中检索有关它的信息。SharedParameterElement从父ParameterElement类继承GetDefinition()方法。GetDefinition()返回表示文档中参数定义的InternalDefinition,而不是存储在共享参数文件中的共享参数的ExternalDefinition。SharedParameterElement还通过GuidValue属性提供对标识共享参数的Guid的访问。

该类的静态Create()方法可以从ExternalDefinition在文档中创建一个新的SharedParameterElement。

静态函数可以从给定的Guid中检索SharedParameterElement。

在下面的示例中,明细表包含一个表示共享参数值的字段。从SharedParameterElement检索共享参数的定义。

代码区域:获取共享参数的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Check if a given shared parameter in a schedule can vary across groups
public bool CanParamVaryAcrossGroups(ViewSchedule schedule, string sharedParamName)
{
bool variesAcrossGroups = false;

int numFields = schedule.Definition.GetFieldCount();
// Find the field with the given name
for (int i = 0; i < numFields; i++)
{
ScheduleField field = schedule.Definition.GetField(i);
if (field.GetName().Contains(sharedParamName))
{
// Get the SharedParameterElement from the field's parameter id
SharedParameterElement spe = schedule.Document.GetElement(field.ParameterId) as SharedParameterElement;
if (spe != null)
{
InternalDefinition definition = spe.GetDefinition();
variesAcrossGroups = definition.VariesAcrossGroups;
}
}
}

return variesAcrossGroups;
}

SharedParameterElements在使用RebarContainers时特别有用。可以将共享参数作为覆盖添加到RebarContainer的参数管理器中。shared参数不需要绑定到要作为覆盖添加的任何类别。下面的示例将给定的共享参数作为重写添加到RebarContainer。

代码区域:使用SharedParameterElement重写RebarContainer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Find the named shared parameter and add it as an override to the parameter manger for the given RebarContainer
void AddSharedParameterOverride(RebarContainer container, string sharedParamName)
{
// find the shared parameter guid
FilteredElementCollector collector = new FilteredElementCollector(container.Document);
collector.OfClass(typeof(SharedParameterElement));
IEnumerable paramCollector = collector.Cast();

foreach (SharedParameterElement spe in paramCollector)
{
if (spe.Name.CompareTo(sharedParamName) == 0)
{
RebarContainerParameterManager paramManager = container.GetParametersManager();
paramManager.AddSharedParameterAsOverride(spe.Id);
break;
}
}
}

全局参数

全局参数支持通过项目文档中定义的特殊参数控制几何约束。

全局参数可用于标注和报告至/自标注,以及设置实例参数的值。它们可用于驱动尺寸或其他元素参数的值,也可由选定尺寸驱动,选定尺寸的值将确定全局参数的值。

本节中的页面

  • 管理全局参数
  • 全局参数基础
  • 报告与非报告参数
  • 公式和全局参数
  • 使用全局参数标注标注

管理全局参数

GlobalParametersManager类提供对特定模型中的全局参数元素的常规信息和数据的访问。

GlobalParametersManager提供了管理项目文档中全局参数的主要访问点。它提供了静态方法来访问和重新排序全局参数,并测试名称的唯一性和ID的有效性。

全局参数

仅在项目文档中支持全局参数,而在族文档中不支持全局参数。然而,即使有项目文件,在某些情况下也可能暂时或永久地不允许使用全局参数。AreGlobalParametersAllowed()方法将指示在指定文档中是否允许全局参数。

如果允许在项目文档中使用全局参数,请使用方法GetAllGlobalParameters()获取指定文档中的所有全局参数,或使用GetGlobalParametersOrdered()获取全局参数的有序列表。检索有序列表时,项目的顺序与Revit用户界面中标准“全局参数”对话框中全局参数的显示顺序相对应。

要按名称获取全局参数,请调用FindByName(),它将返回命名的全局参数的ElementId,如果没有找到具有给定名称的全局参数,则返回ElementId.InvalidElementId。由于全局参数名称必须是唯一的,因此应在创建新的GlobalParameter之前调用IsUniqueName()方法来检查名称。

给定全局参数的ElementId,IsValidGlobalParameter()将确认给定的ElementId是有效的全局参数id。

下面的示例演示如何获取所有全局参数(如果文档中允许全局参数)。

代码区域:获取全局参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
///
/// Returns all global parameter elements defined in the given document.
///

/// Revit project document.
/// A set of ElementIds of global parameter elements
public ISet GetAllGlobalParameters(Document document)
{
// Global parameters are not available in all documents.
// They are available in projects, but not in families.
if (GlobalParametersManager.AreGlobalParametersAllowed(document))
{
return GlobalParametersManager.GetAllGlobalParameters(document);
}

// return an empty set if global parameters are not available in the document
return new HashSet();
}

重新排序全局参数

GlobalParametersManager提供了更改项目文档中全局参数的给定顺序的方法。这些操作对全局参数本身没有影响。重新排列的顺序仅在Revit的标准“全局参数”对话框中可见,并反映在GetGlobalParametersOrdered()方法中。

  • SortParameters()-按字母顺序的升序或降序对全局参数进行排序,但仅在其各自的参数组范围内。
  • MoveParameterDownOrder()-按当前顺序向下移动给定参数。
  • MoveParameterUpOrder()-将给定参数按当前顺序上移。一个参数只能在其参数组内移动,所以如果一个参数因为位于其组的边界而不能再移动,MoveParameter方法将返回False。

全局参数基础

GlobalParameter类表示项目文档中的全局参数,可用于创建和修改全局参数。

创建全局参数

全局参数只能在项目文档中创建,而不能在族中创建。全局参数通过静态Create()方法在给定文档中创建,具有给定的名称和参数类型。每个新参数在文档中必须有一个唯一的名称,可以使用静态GlobalParametersManager.IsUniqueName()方法确定该名称。全局参数几乎可以使用任何类型的数据创建,但有几种类型目前不受支持,例如ElementId类型。使用静态GlobalParameter.IsValidDataType()方法测试特定数据类型是否适合全局参数。

代码区域:创建新的全局参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/// 

/// Creates a new Global Parameter of type Length, assigns it an initial value,
/// and uses it to label a set of input dimension elements.
///

/// Revit project document in which to create the parameter.
/// Name of the global parameter to create.
/// A value the new global parameter is to have.
/// A set of dimension to labe by the new global parameter.
/// ElementId of the new GlobalParameter
public ElementId CreateNewGlobalParameter(Document document, String name, double value, ISet dimensionsToLabel)
{
if (!GlobalParametersManager.AreGlobalParametersAllowed(document))
throw new System.InvalidOperationException("Global parameters are not permitted in the given document");

if (!GlobalParametersManager.IsUniqueName(document, name))
throw new System.ArgumentException("Global parameter with such name already exists in the document", "name");

ElementId gpid = ElementId.InvalidElementId;

// creation of any element must be in a transaction
using (Transaction trans = new Transaction(document, "Create Global Parameter"))
{
trans.Start();

// create a GP with the given name and type Length
GlobalParameter gp = GlobalParameter.Create(document, name, ParameterType.Length);
if (gp != null)
{
// if created successfully, assign it a value
// note: parameters of type Length accept Double values
gp.SetValue(new DoubleParameterValue(value));

// if a collection of dimensions was given, label them with this new parameter
foreach (ElementId elemid in dimensionsToLabel)
{
// not just any dimension is allowed to be labeled
// check first to avoid exceptions
if (gp.CanLabelDimension(elemid))
{
gp.LabelDimension(elemid);
}
}

gpid = gp.Id;
}
trans.Commit();
}

return gpid;
}

获取和设置全局参数的值

所有全局参数,无论是公式驱动的、尺寸驱动的还是独立的,都有值。可以通过调用GetValue()方法来获取值。该方法返回的对象是从ParameterValue类派生的类之一的实例:

  • IntegerParameterValue
  • DoubleParameterValue
  • StringParameterValue

所有派生类都只有一个属性Value,它获取或设置相应类型的值。

具体实例由创建时指定的全局参数的类型确定。既不是公式驱动的参数也不是维度驱动的参数(报告)可以被赋值。要使用的方法是SetValue(),它接受GetValue()返回的相同类型的参数值。但是,类型也可以很容易地推导出来:Text参数只接受StringParameterValue。Integer 和 YesNo 参数仅接受IntegerParameterValue。所有其他参数仅接受DoubleParameterValue。

受全局参数影响的元素

全局参数可以与其他全局参数以及常规族实例参数相关联(常规族实例参数可以通过指定公式将全局参数报告为它们的值)。有两种方法可用于查找参数之间的关系:GlobalParameter.GetAffectedGlobalParameters()和GlobalParameter.GetAffectedElements()。前者返回在其各自的公式中引用特定全局参数的所有其他全局参数。后一个方法返回一组所有元素,其中一些参数由全局参数控制。这两个方法与GlobalParameter.GetLabeledDimensions()一起可以帮助确定模型元素如何通过全局参数相互关联。

可以在Parameter类中找到用于维护元素属性和全局参数之间的关联的方法。

报告与非报告参数

全局参数类型的最大区别是它们是报告参数还是非报告参数。

什么是报告和非报告参数?

有几种方法可以对全局参数进行分类,但最重要的分类可能源于GlobalParameter.IsReporting属性,该属性将全局参数分为两组-报告和非报告。报告参数的重要性在于它们的值由报告参数标记的维度驱动。这意味着报告参数的值反映了尺寸(长度或角度)的值,并在尺寸更改时更新。非报告参数的行为方式相反-它们驱动已由其标记的尺寸的值,这导致通过全局参数的值控制模型的几何体。

报告参数在几个方面受到限制。它们只能是“长度”或“角度”类型,这是因为尺寸必须能够驱动值。出于同样的原因,报告参数可能没有公式。

另一方面,非报告参数几乎可以是任何类型(长度、宽度、面积等)。ElementId类型除外。此外,非报告参数可能已分配公式,其中其他全局参数可用作参数。这样,一个全局参数的值可以从其他参数(或多个参数)导出,而其他参数可以是报告或非报告的。

全局参数的其他重要属性是IsDrivenByDimension和IsDrivenByFormula,它们是互斥的-分配了公式的参数不能由维驱动(也不能由报告驱动),反之亦然。

使全局参数报告或不报告

全局参数在创建时最初是非报告的,但一旦创建了全局参数并且属于合格类型,就可以使用GlobalParameter.IsReporting属性将其设置为报告。使用GlobalParameter.HasValidTypeForReporting()确保可以使特定数据类型进行报告。请注意,当一个参数标记了多个维度后,该参数可能无法进行报告。这是因为报告参数只能标记一个维度(并由一个维驱动)。

生成参数报告的另一种方法是通过GlobalParameter.SetDrivingDimension()方法,该方法通过全局参数标记一个维度,如果尚未报告,则也生成参数报告。

尽管由尺寸驱动的参数会自动生成报告,但由公式驱动的参数则不会。为了设置公式,全局参数必须为非报告参数。因此,在分配公式之前,必须首先将报告参数更改为非报告参数。

公式和全局参数

公式可以分配给非报告参数。

与族参数一样,可以使用GlobalParameter.SetFormula()方法将公式分配给全局参数。由于要设置公式,全局参数必须为非报告参数,因此在分配公式之前,必须将报告参数更改为非报告参数。

计算公式的值必须与参数的值类型兼容。例如,允许在分配给Double(Number)参数的公式中使用NULL参数,反之亦然。但是,不允许在公式中的参数类型为“ether”或“Number”的参数中使用LengthAngle参数。

公式可以包括所有标准的算术运算和逻辑运算(如函数andornot)。逻辑运算的输入必须是布尔值(YesNo类型的参数)。因此,算术运算只能应用于数值。虽然字符串(文本)参数不支持任何操作,但字符串可以用作逻辑If操作的结果。根据其类型(和单位),不同值类型的参数可以组合。但是,无单位值(例如,“”“Number(double)”)只能相互组合。

由于公式可能会变得非常复杂,并且由于某些公式无法分配给某些参数,因此可以使用IsValidFormula()方法来测试公式对于全局参数是否有效。如果调用SetFormula()时全局参数的公式无效,则将引发异常。

GetFormula()将以字符串的形式返回当前公式。

下面的代码示例创建四个全局参数,然后将公式设置为1,以便它的值为其他两个参数中的任何一个,具体取决于第四个参数的布尔值。

代码区域:设置公式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public void SetCombinationParameters(Document document)
{
GlobalParameter gpB = null;
GlobalParameter gpT = null;
GlobalParameter gpF = null;
GlobalParameter gpX = null;

int TRUE = 1;
int FALSE = 0;

// transaction to create global parameters and set their values
using (Transaction trans = new Transaction(document, "Creating global parameters"))
{
// create 4 new global parameters

trans.Start();

gpB = GlobalParameter.Create(document, "GPB", ParameterType.YesNo);
gpT = GlobalParameter.Create(document, "GPT", ParameterType.Text);
gpF = GlobalParameter.Create(document, "GPF", ParameterType.Text);
gpX = GlobalParameter.Create(document, "GPX", ParameterType.Text);

// assign initial values and a formula to the global parameters

gpB.SetValue(new IntegerParameterValue(TRUE));
gpT.SetValue(new StringParameterValue("TypeA"));
gpF.SetValue(new StringParameterValue("TypeB"));

// Set the formula to GPX so that its final value is either the value of GPT (TypeA)
// or GPF (TypeB) depending on whether the value of GPB is True or False.
// Note: in this particular case we are certain the formula is valid, but if weren't
// certain, we could use a validation method as we are now going to illustrate here:
string expression = "if(GPB,GPT,GPF)"; // XPX <== if (GPB == TRUE) then GPT else GPF
if (gpX.IsValidFormula(expression))
{
gpX.SetFormula(expression); }

trans.Commit();
}

// we can test that the formula works
// since the boolean value is TRUE, the value of the GPX parameter
// should be the same as the value of the GPT parameters

StringParameterValue sTrue = gpT.GetValue() as StringParameterValue;
StringParameterValue sFalse = gpF.GetValue() as StringParameterValue;
StringParameterValue sValue = gpX.GetValue() as StringParameterValue;

if (sValue.Value != sTrue.Value)
{
TaskDialog.Show("Error", "Unexpected value of a global parameter");
}

// we can also test that evaluation of the formula is affected by changes

using (Transaction trans = new Transaction(document, "Change value of a YesNo parameter"))
{
trans.Start();
gpB.SetValue(new IntegerParameterValue(FALSE));
trans.Commit();
}

sValue = gpX.GetValue() as StringParameterValue;

if (sValue.Value != sFalse.Value)
{
TaskDialog.Show("Error", "Unexpected value of a global parameter");
}

}

使用全局参数标注标注

全局参数的一个关键特性是它们能够“标记”尺寸。

当维度由全局参数标记时,其值要么由参数控制(非报告),要么驱动参数的值(报告)。需要注意的是,报告参数最多只能标记一个维对象,这意味着参数只能由一个维驱动。如果尺寸标注有多个线段,并且由非报告参数标记,则每个线段的值将由该参数驱动。多段维不能用报告参数标记。

如果该维度已被另一个全局参数标记,则再次标记它将自动将其与该参数分离。

目前,只能标记单个线性角度尺寸,但也有其他限制。使用CanLabelDimension()方法来确定是否可以标记特定的维度元素。此外,由于参数的值和由其标记的尺寸相互依赖,因此全局参数的数据类型必须是LengthAngle,因为这是尺寸可以表示的唯一单位。

下面的示例创建一个全局参数,并使用它来标记给定维度元素集。

代码区域:标签尺寸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public int DriveSelectedDimensions(Document document, string name, double value, ISet dimset)
{
if (!GlobalParametersManager.AreGlobalParametersAllowed(document))
throw new System.InvalidOperationException("Global parameters are not permitted in the given document");

if (!GlobalParametersManager.IsUniqueName(document, name))
throw new System.ArgumentException("Global parameter with such name already exists in the document", "name");

if (value <= 0.0)
throw new System.ArgumentException("Value of a global parameter that drives dimension must be a positive number", "value");

int nLabeledDims = 0; // number of labeled dimensions (for testing)

// creation of any element must be in a transaction
using (Transaction trans = new Transaction(document, "Create Global Parameter"))
{
trans.Start();

// create a GP with the given name and type Length
// Note: Length (or Angle) is required type of global parameters that are to label a dimension
GlobalParameter newgp = GlobalParameter.Create(document, name, ParameterType.Length);
if (newgp != null)
{
newgp.SetValue(new DoubleParameterValue(value));

// use the parameter to label the given dimensions
foreach (ElementId elemid in dimset)
{
// not just any dimension is allowed to be labeled
// check first to avoid exceptions
if (newgp.CanLabelDimension(elemid))
{
newgp.LabelDimension(elemid);
nLabeledDims += 1;
}
}

trans.Commit();
}
}

// for illustration purposes only, we'll test the results of our modifications

// 1.) Check the new parameter can be found

ElementId gpid = GlobalParametersManager.FindByName(document,name);
if (gpid == ElementId.InvalidElementId)
{
TaskDialog.Show("Error", "Failed to find a newly created global parameter");
}

GlobalParameter gp = document.GetElement(gpid) as GlobalParameter;

// 2. Check the number of labeled dimension is as expected

ISet labeledSet = gp.GetLabeledDimensions();
if (labeledSet.Count != nLabeledDims)
{
TaskDialog.Show("Error", "Have not found all the dimension that were labeled.");
}

return labeledSet.Count;
}

SetDrivingDimension()方法结合了两个操作:a)如果参数尚未报告,则进行参数报告,以及B)使用它标记给定维。因此,全局参数必须符合报告条件,并且不得用于标记多个维。有关报告参数的详细信息,请参阅报告参数与非报告参数页面 如果此参数已由另一个维度驱动,则在标记给定的维度之前,将首先取消标记另一个维度。这是因为报告参数一次只能标记一个维度(即,它只能由一个维度驱动)。 下一个示例创建由尺寸值驱动的全局参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public bool AssignDrivingDimension(Document document, ElementId gpid, ElementId dimid)
{
// we expect to find the global parameter in the document
GlobalParameter gp = document.GetElement(gpid) as GlobalParameter;
if (gp == null)
return false;

// we expect to find the given dimension in the document
Dimension dim = document.GetElement(dimid) as Dimension;
if (dim == null)
return false;

// not every global parameter can label
// and not every dimension can be labeled
if (!gp.CanLabelDimension(dimid))
return false;

// we need a transaction to modify the model
using (Transaction trans = new Transaction(document,"Assign a driving dimension"))
{
trans.Start();

// we cannot assign a driving dimension to a global
// parameter that is already used to label other dimensions
ISet dimset = gp.GetLabeledDimensions();
foreach (ElementId elemid in dimset)
{
gp.UnlabelDimension(elemid);
}

// with the GP free of all previously labels (if there were any)
gp.SetDrivingDimension(dimid);

// we should be able to commit, but we test the result anyway
if (trans.Commit() != TransactionStatus.Committed)
return false;
}

return true;
}

参数

Parameter类包含给定参数的值。

Autodesk Revit中的所有图元都包含参数,这些参数可以作为一个集合或单独检索。可以使用BuiltInParameter枚举、Definition对象或Shared Parameter对象从任何Element中获取单个参数对象。参数中包含的数据可以是Double、String、String或ElementId,如其String Type属性所示。对于值类型,DisplayUnitType属性将指示用于参数值的显示单位。Parameter对象还包含一个Definition对象,用于描述参数的数据类型、名称和其他详细信息。

StorageType

储存类型描述内部存储的参数值的类型。

根据属性值,使用相应的get和set方法来检索和设置参数数据值。

“储存类型”是一种枚举类型,列出了Revit支持的所有内部参数数据存储类型:

Member Name 成员名称 Description 描述
String 内部数据存储为字符串。
ElementId 数据类型表示一个元素,并存储为元素ID。
Double 数据在内部存储为8字节浮点数。
Integer 内部数据存储为有符号的32位整数。
None 无表示无效的存储类型。仅供内部使用。

在大多数情况下,ElementId值为正数。但是,它可以是负数。当ElementId值为负时,它不表示元素,而是具有另一种含义。例如,梁的垂直投影的存储类型参数为ElementId。当参数值为Level 1或Level 2时,ElementId值为正,并与该级别的ElementId相对应。但是,当参数值设置为“自动检测”、“梁中心”或“梁顶部”时,ElementId值为负值。 下面的代码示例显示如何根据参数的类型检查参数的值是否可以设置为double值:

代码区域:检查参数的类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public bool SetParameter(Parameter parameter, double value)
{
bool result = false;
//if the parameter is readonly, you can't change the value of it
if (null != parameter && !parameter.IsReadOnly)
{
StorageType parameterType = parameter.StorageType;
if (StorageType.Double != parameterType)
{
throw new Exception("The storagetypes of value and parameter are different!");
}

//If successful, the result is true
result = parameter.Set(value);
}

return result;
}

Set()方法返回值指示参数值已更改。Set()方法在参数值被更改时返回true,否则返回false。 并非所有参数都是可写的。如果参数为只读,则引发异常。 ## AsValueString()和SetValueString() 这两个Parameter类方法仅适用于值类型参数,这些参数是表示测量量的双精度或整数参数。 使用AsValueString()方法以带有度量单位的字符串形式获取参数值。例如,“底部偏移”值(墙参数)为“双精度”值。通常,该值在“图元属性”中显示为字符串,如-20 ‘0”。使用AsValueString()方法,您可以直接获得-20 ‘0”字符串值。使用AsDouble()方法,可以得到一个不带度量单位的double值,如-20。 使用SetValueString()方法更改值类型参数的值,而不是使用Set()方法。下面的代码示例说明如何使用SetValueString()方法更改参数值:

使用参数. SetValueString()

1
2
3
4
5
6
7
8
9
10
public bool SetWithValueString(Parameter foundParameter)
{
bool result = false;
if (!foundParameter.IsReadOnly)
{
//If successful, the result is true
result = foundParameter.SetValueString("-22\'3\"");
}
return result;
}

全局参数关联

Parameter类有几种方法用于维护元素参数和全局参数之间的关联。方法GetAssociatedGlobalParameter()返回当前与参数关联的全局参数的ElementId(如果有)。如果此参数未与任何全局参数关联,则返回InvalidElementId。InvalidElementId也会在为一个甚至不能与全局参数相关联的参数(即一个不可参数化的参数或一个带有公式的参数)调用时返回。

有两种方法可以确定参数是否可以与全局参数关联。参数.CanBeAssociatedWithGlobalParameters()测试参数是否可以与任何全局参数相关联。只有定义为可参数化的属性才能与全局参数相关联。这不包括任何只读参数和公式驱动参数,以及具有Revit施加的其他显式或隐式限制的参数。若要测试特定全局参数是否可以与此参数关联,请使用Parameter.CanBeAssociatedWithGlobalParameter()。请记住,参数的值类型必须与全局参数的类型匹配,才能创建关联。

对于可以与全局参数关联的参数,请使用AssociateWithGlobalParameter()创建关联。关联后,可以在以后通过调用DissociateFromGlobalParameter()方法解除参数关联

注:翻译自Revit API Developers Guide