ADN Open CIS
Сообщество программистов Autodesk в СНГ

20/12/2013

Определение типа общего параметра

В статье обсудим вопрос, который задали мне недавно, но его мы также обсуждали и ранее, о том как определить является ли параметр, из списка всех общих параметров проекта, параметром Типа или Экземпляра.

Вопрос: Я никак не могу найти способ, с помощью которого можно определить, является ли параметр параметром типа или экземпляра с помощью Revit API. Единственная зацепка, которую я смог найти, это свойство FamilyParameter.IsInstance. Но это применимо только к редактору семейств. А мне же нужно узнать задан ли параметр для типа или экземпляра для всех общих параметров проекта. Можно это сделать или нет?

Ответ: Самый простой способ - просто взять и проверить свойство Element у класса Parameter.

Свойство Parameter.Element даст вам знать какому элементу принадлежит данный параметр.

Если этот элемент наследуется от класса ElementType, то вы имеете дело с параметром Типа, в противном же случае – это параметр Экземпляра.

Но, вся проблема в том, что если вы перечисляете определения общих параметров из проекта с помощью свойства Document.ParameterBindings, то такой возможности у вас не будет, так как нет элемента, по которому можно проверить.

Сам по себе параметр не содержит такой информации, так как он является лишь описанием данных и не обязан знать кто и как будет его использовать.

Коллекция ParameterBindings содержит в себе сопоставления описаний параметров и их привязкой к элементам. Давайте-ка по подробней с этим разберемся.

Ниже представлен список предыдущих дискуссий на похожие темы:

Вернемся к истокам на мгновение и взглянем в файл справки Revit API на определения классов, которые участвуют в этих темах.

Класс ElementBinding –базовый класс для всех типов привязки параметра к элементу.

Класс TypeBindings – класс, наследуемый от ElementBinding и определяет объекты для привязки параметра к типоразмерам Revit, например, к типоразмеру стены.

Основное отличие от привязки к Экземпляру заключается в том, что привязка к типоразмеру распространяется на все элементы, которые используют данный типоразмер. Когда вы меняете значение параметра типоразмера, то оно влияет на все экземпляры этого типа.

В примере кода вы можете посмотреть, как привязать параметр к типоразмеру стены.

Класс InstanceBindings – класс, наследуемый от ElementBinding, который определяет привязку параметра и его описания к конкретному экземпляру, например, к стене.

Привязав однажды параметр к экземпляру, этот параметр появится у всех экземпляров. Изменения значения этого параметра на одном из элементов, никак не повлияют на другие элементы.

В примерах кода также вы можете найти как привязывать параметр к экземпляру.

Таким образом, в вашем конкретном случае, определить является ли параметр параметром Типа или Экземпляра, можно лишь взглянув на тип привязки.

Я переделал одну старую тестовую команду из примеров The Building Coder, которая и раньше не делала ничего полезного, CmdListSharedParams, таким образом, что теперь она определяет какие параметры являются параметрами Типа, а какие параметрами Экземпляра.

Команда получилась довольно простой. Все что вам нужно, это получить список всех привязок и проверить тип каждой из них. Целиком команда выглядит вот так:

Код - C#: [Выделить]
  1. [Transaction( TransactionMode.ReadOnly )]
  2. class CmdListSharedParams : IExternalCommand
  3. {
  4.   public Result Execute(
  5.     ExternalCommandData commandData,
  6.     ref string message,
  7.     ElementSet elements )
  8.   {
  9.     UIApplication app = commandData.Application;
  10.     UIDocument uidoc = app.ActiveUIDocument;
  11.     Document doc = uidoc.Document;
  12.  
  13.     BindingMap bindings = doc.ParameterBindings;
  14.  
  15.     int n = bindings.Size;
  16.  
  17.     Debug.Print( "{0} shared parementer{1} defined{2}",
  18.       n, Util.PluralSuffix( n ), Util.DotOrColon( n ) );
  19.  
  20.     if( 0 < n )
  21.     {
  22.       DefinitionBindingMapIterator it
  23.         = bindings.ForwardIterator();
  24.  
  25.       while( it.MoveNext() )
  26.       {
  27.         Definition d = it.Key as Definition;
  28.         Binding b = it.Current as Binding;
  29.  
  30.         Debug.Assert( b is ElementBinding,
  31.           "all Binding instances are ElementBinding instances" );
  32.  
  33.         Debug.Assert( b is InstanceBinding
  34.           || b is TypeBinding,
  35.           "all bindings are either instance or type" );
  36.  
  37.         // All definitions obtained in this manner
  38.         // are InternalDefinition instances, even
  39.         // if they are actually associated with
  40.         // shared parameters, i.e. external.
  41.  
  42.         Debug.Assert( d is InternalDefinition,
  43.           "all definitions obtained from BindingMap are internal" );
  44.  
  45.         string sbinding = ( b is InstanceBinding )
  46.           ? "instance"
  47.           : "type";
  48.  
  49.         Debug.Print( "{0}: {1}", d.Name, sbinding );
  50.       }
  51.     }
  52.     return Result.Succeeded;
  53.   }
  54. }

Обновленная версия примеров с командой CmdListSharedParams , описанной выше, опубликовано под версией 2014.0.105.3.

Источник: http://thebuildingcoder.typepad.com/blog/2013/11/determining-whether-parameter-is-type-or-instance-bound.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=406

Опубликовано 20.12.2013
Отредактировано 20.12.2013 в 10:34:35