如何将共享参数绑定到类型和实例的元素
How to bind a Shared Parameter to elements of both Type and Instance
使用 Revit 2018.1 API。我以编程方式创建共享参数。这很好用。我还可以将该参数绑定到不同的元素类型(类别),例如 Windows 或门。然而,一旦完成,我就很难创建一个新的绑定到例如一个不是家庭类型的房间,并且应该绑定到 instance
我有一些代码是别人提供给我的。我相信创建共享参数或按名称找到共享参数并为类别创建绑定的部分来自一些最佳实践。 HelpParams.cs。
//this code is all about finding a parameter
Application app = doc.Application;
DefinitionBindingMapIterator iterator = doc.ParameterBindings.ForwardIterator();
while (iterator.MoveNext())
{
Definition definition = iterator.Key;
if (paramName.Equals(definition.Name, StringComparison.CurrentCultureIgnoreCase))
{
ElementBinding elementBinding = (ElementBinding)iterator.Current;
CategorySet categorySet = elementBinding.Categories;
if (elementBinding.Categories.Contains(elementCategory))
{
if (paramType != definition.ParameterType)
{
return BindSharedParamResult.eWrongParamType;
}
var bindingType = elementBinding.GetType();
if ((instanceBinding && bindingType == typeof(InstanceBinding)) || (!instanceBinding && bindingType == typeof(TypeBinding)))
{
return BindSharedParamResult.eAlreadyBound;
}
}
if (!categorySet.Contains(elementCategory))
{
//HK this is the original code that was in the if (!categorySet.Contains(elementCategory)) above
elementBinding.Categories.Insert(elementCategory);
if (doc.ParameterBindings.ReInsert(definition, elementBinding))
{
return BindSharedParamResult.eSuccessfullyBound;
}
else
{
WriteToLog("BindSharedParam unable to update category for " + definition.Name);
return BindSharedParamResult.eFailed;
}
}
return BindSharedParamResult.eAlreadyBound;
}
//This code shows how to create new binding for an element category
CategorySet categorySet = app.Create.NewCategorySet();
categorySet.Insert(elementCategory);
Binding newBinding = null;
if (instanceBinding)
{
newBinding = app.Create.NewInstanceBinding(categorySet);
}
else
{
newBinding = app.Create.NewTypeBinding(categorySet);
}
//HK insert success
var inserted = doc.ParameterBindings.Insert(definition, newBinding);
if (inserted)
{
return BindSharedParamResult.eSuccessfullyBound;
}
}
如果我有要创建的参数。我有将创建共享参数 (SP) 的代码。这样可行。此外,如果代码的第一部分尝试按名称查找参数,将第一次找不到参数,并且将在代码的第二部分为类型或实例创建一个新绑定,具体取决于输入参数(bool instanceBinding) 到此代码所在的函数。
所以如果第一个元素类别是 Windows。将创建 SP,以及类型 "NewTypeBinding" 的新绑定。一切正常。如果我然后尝试将相同的 SP 绑定到另一种类型,例如 Doors,将通过名称找到参数,但是 ElementBinding 的类型是 "Type" 而不是实例。在 Doors 的情况下,这有效,并且参数将被绑定。
然后我将尝试对 Room 元素类别执行相同的操作。现在这不是家族类型,因此它没有类型信息,只有实例。代码将找到相同的参数,通过代码正常流程,但由于唯一可用的绑定元素是类型,因此当尝试绑定(插入)参数时会出现异常
我尝试了一些标志和测试,以检查参数 (bool instanceBinding) 是否与我们迭代的 ParameterBinding 中的 ElementBinding 类型不同。通过这样做,我可以强制代码执行转到代码的第二部分,然后我在该处尝试创建类型为 "instance" 的新出价。这是行不通的。
var inserted = doc.ParameterBindings.Insert(definition, newBinding);
插入的是 "false".
相反的情况也会发生。如果我从 Rooms 开始,第一个绑定将是实例类型。然而,由于类型可以有实例,代码执行不会失败,并且类型将具有实例级别的参数。
有没有一种方法可以使用一个共享参数并将其绑定到类型和实例???
我相信不会。共享参数绑定到类型或实例,而不是两者。
使用 Revit 2018.1 API。我以编程方式创建共享参数。这很好用。我还可以将该参数绑定到不同的元素类型(类别),例如 Windows 或门。然而,一旦完成,我就很难创建一个新的绑定到例如一个不是家庭类型的房间,并且应该绑定到 instance
我有一些代码是别人提供给我的。我相信创建共享参数或按名称找到共享参数并为类别创建绑定的部分来自一些最佳实践。 HelpParams.cs。
//this code is all about finding a parameter
Application app = doc.Application;
DefinitionBindingMapIterator iterator = doc.ParameterBindings.ForwardIterator();
while (iterator.MoveNext())
{
Definition definition = iterator.Key;
if (paramName.Equals(definition.Name, StringComparison.CurrentCultureIgnoreCase))
{
ElementBinding elementBinding = (ElementBinding)iterator.Current;
CategorySet categorySet = elementBinding.Categories;
if (elementBinding.Categories.Contains(elementCategory))
{
if (paramType != definition.ParameterType)
{
return BindSharedParamResult.eWrongParamType;
}
var bindingType = elementBinding.GetType();
if ((instanceBinding && bindingType == typeof(InstanceBinding)) || (!instanceBinding && bindingType == typeof(TypeBinding)))
{
return BindSharedParamResult.eAlreadyBound;
}
}
if (!categorySet.Contains(elementCategory))
{
//HK this is the original code that was in the if (!categorySet.Contains(elementCategory)) above
elementBinding.Categories.Insert(elementCategory);
if (doc.ParameterBindings.ReInsert(definition, elementBinding))
{
return BindSharedParamResult.eSuccessfullyBound;
}
else
{
WriteToLog("BindSharedParam unable to update category for " + definition.Name);
return BindSharedParamResult.eFailed;
}
}
return BindSharedParamResult.eAlreadyBound;
}
//This code shows how to create new binding for an element category
CategorySet categorySet = app.Create.NewCategorySet();
categorySet.Insert(elementCategory);
Binding newBinding = null;
if (instanceBinding)
{
newBinding = app.Create.NewInstanceBinding(categorySet);
}
else
{
newBinding = app.Create.NewTypeBinding(categorySet);
}
//HK insert success
var inserted = doc.ParameterBindings.Insert(definition, newBinding);
if (inserted)
{
return BindSharedParamResult.eSuccessfullyBound;
}
}
如果我有要创建的参数。我有将创建共享参数 (SP) 的代码。这样可行。此外,如果代码的第一部分尝试按名称查找参数,将第一次找不到参数,并且将在代码的第二部分为类型或实例创建一个新绑定,具体取决于输入参数(bool instanceBinding) 到此代码所在的函数。
所以如果第一个元素类别是 Windows。将创建 SP,以及类型 "NewTypeBinding" 的新绑定。一切正常。如果我然后尝试将相同的 SP 绑定到另一种类型,例如 Doors,将通过名称找到参数,但是 ElementBinding 的类型是 "Type" 而不是实例。在 Doors 的情况下,这有效,并且参数将被绑定。 然后我将尝试对 Room 元素类别执行相同的操作。现在这不是家族类型,因此它没有类型信息,只有实例。代码将找到相同的参数,通过代码正常流程,但由于唯一可用的绑定元素是类型,因此当尝试绑定(插入)参数时会出现异常
我尝试了一些标志和测试,以检查参数 (bool instanceBinding) 是否与我们迭代的 ParameterBinding 中的 ElementBinding 类型不同。通过这样做,我可以强制代码执行转到代码的第二部分,然后我在该处尝试创建类型为 "instance" 的新出价。这是行不通的。 var inserted = doc.ParameterBindings.Insert(definition, newBinding); 插入的是 "false".
相反的情况也会发生。如果我从 Rooms 开始,第一个绑定将是实例类型。然而,由于类型可以有实例,代码执行不会失败,并且类型将具有实例级别的参数。
有没有一种方法可以使用一个共享参数并将其绑定到类型和实例???
我相信不会。共享参数绑定到类型或实例,而不是两者。