Определение типа общего параметра
В статье обсудим вопрос, который задали мне недавно, но его мы также обсуждали и ранее, о том как определить является ли параметр, из списка всех общих параметров проекта, параметром Типа или Экземпляра.
Вопрос: Я никак не могу найти способ, с помощью которого можно определить, является ли параметр параметром типа или экземпляра с помощью Revit API. Единственная зацепка, которую я смог найти, это свойство FamilyParameter.IsInstance. Но это применимо только к редактору семейств. А мне же нужно узнать задан ли параметр для типа или экземпляра для всех общих параметров проекта. Можно это сделать или нет?
Ответ: Самый простой способ - просто взять и проверить свойство Element у класса Parameter.
Свойство Parameter.Element даст вам знать какому элементу принадлежит данный параметр.
Если этот элемент наследуется от класса ElementType, то вы имеете дело с параметром Типа, в противном же случае – это параметр Экземпляра.
Но, вся проблема в том, что если вы перечисляете определения общих параметров из проекта с помощью свойства Document.ParameterBindings, то такой возможности у вас не будет, так как нет элемента, по которому можно проверить.
Сам по себе параметр не содержит такой информации, так как он является лишь описанием данных и не обязан знать кто и как будет его использовать.
Коллекция ParameterBindings содержит в себе сопоставления описаний параметров и их привязкой к элементам. Давайте-ка по подробней с этим разберемся.
Ниже представлен список предыдущих дискуссий на похожие темы:
- Создание общего параметра для модели групп (на англ.)
- Добавление категории к параметру (на англ.)
- Общий параметр типа (на англ.)
- Добавление категории к общему параметру(на англ.)
- Ошибка при обращении к списку категорий (на англ.)
- Свойство IsShared для класса FamilyParameter
- Как поменять параметр семейства с параметра Типа на Экземпляр (на англ.)
Вернемся к истокам на мгновение и взглянем в файл справки Revit API на определения классов, которые участвуют в этих темах.
Класс ElementBinding –базовый класс для всех типов привязки параметра к элементу.
Класс TypeBindings – класс, наследуемый от ElementBinding и определяет объекты для привязки параметра к типоразмерам Revit, например, к типоразмеру стены.
Основное отличие от привязки к Экземпляру заключается в том, что привязка к типоразмеру распространяется на все элементы, которые используют данный типоразмер. Когда вы меняете значение параметра типоразмера, то оно влияет на все экземпляры этого типа.
В примере кода вы можете посмотреть, как привязать параметр к типоразмеру стены.
Класс InstanceBindings – класс, наследуемый от ElementBinding, который определяет привязку параметра и его описания к конкретному экземпляру, например, к стене.
Привязав однажды параметр к экземпляру, этот параметр появится у всех экземпляров. Изменения значения этого параметра на одном из элементов, никак не повлияют на другие элементы.
В примерах кода также вы можете найти как привязывать параметр к экземпляру.
Таким образом, в вашем конкретном случае, определить является ли параметр параметром Типа или Экземпляра, можно лишь взглянув на тип привязки.
Я переделал одну старую тестовую команду из примеров The Building Coder, которая и раньше не делала ничего полезного, CmdListSharedParams, таким образом, что теперь она определяет какие параметры являются параметрами Типа, а какие параметрами Экземпляра.
Команда получилась довольно простой. Все что вам нужно, это получить список всех привязок и проверить тип каждой из них. Целиком команда выглядит вот так:
- [Transaction( TransactionMode.ReadOnly )]
- class CmdListSharedParams : IExternalCommand
- {
- public Result Execute(
- ExternalCommandData commandData,
- ref string message,
- ElementSet elements )
- {
- UIApplication app = commandData.Application;
- UIDocument uidoc = app.ActiveUIDocument;
- Document doc = uidoc.Document;
- BindingMap bindings = doc.ParameterBindings;
- int n = bindings.Size;
- Debug.Print( "{0} shared parementer{1} defined{2}",
- n, Util.PluralSuffix( n ), Util.DotOrColon( n ) );
- if( 0 < n )
- {
- DefinitionBindingMapIterator it
- = bindings.ForwardIterator();
- while( it.MoveNext() )
- {
- Definition d = it.Key as Definition;
- Binding b = it.Current as Binding;
- Debug.Assert( b is ElementBinding,
- "all Binding instances are ElementBinding instances" );
- Debug.Assert( b is InstanceBinding
- || b is TypeBinding,
- "all bindings are either instance or type" );
- // All definitions obtained in this manner
- // are InternalDefinition instances, even
- // if they are actually associated with
- // shared parameters, i.e. external.
- Debug.Assert( d is InternalDefinition,
- "all definitions obtained from BindingMap are internal" );
- string sbinding = ( b is InstanceBinding )
- ? "instance"
- : "type";
- Debug.Print( "{0}: {1}", d.Name, sbinding );
- }
- }
- return Result.Succeeded;
- }
- }
Обновленная версия примеров с командой CmdListSharedParams , описанной выше, опубликовано под версией 2014.0.105.3.
Обсуждение: http://adn-cis.org/forum/index.php?topic=406
Опубликовано 20.12.2013Отредактировано 20.12.2013 в 10:34:35