Стояла у меня задача, для выполнения которой требовалось создание собственного типа для системного семейства Текст (Текстовое примечание).
Немного поискав информацию на просторах интернета, я наткнулся на данный пример, объясняющий, что для создания типа требуется создавать дубликат существующего типа. Вот только в примере совсем не уделено внимание тому, как и какие параметры задавать. Особенно остро стоит вопрос задания значения для параметра «Цвет».
Почитав в теме комментарии, я понял, что вопрос волновал многих и, к моему сожалению, в комментариях нет правильного ответа. Я решил исправить эту маленькую несправедливость и сделал небольшой пример создания типа для системного семейства Текст. Все пояснения я оставил в виде комментариев к коду.
Вот и сам пример:
using System.Drawing;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace TextNoteTypeExample
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
// Текущий документ
Document doc = commandData.Application.ActiveUIDocument.Document;
/* Создание типа для текста (текстовое примечание) «с нуля»
* не предусмотрено в Revit API. Решением является дублирование
* существующего типа и задание ему нужных значений параметров. */
//Поэтому сначала получаем все типы для текста в документе и берем первый попавшийся:
var existingTextNoteType =
new FilteredElementCollector(doc).OfClass(typeof(TextNoteType)).FirstElement() as TextNoteType;
if (existingTextNoteType != null)
using (Transaction tr = new Transaction(doc, "TextNoteTypeExample"))
{
tr.Start();
/* При создании дубликата типа требуется указать новое имя.
* В данном примере я опущу валидацию имени для нового типа,
* однако Вы должны учитывать, что имя должно быть уникальным
* для текущего документа (т.е. нельзя создать двух типов
* с одинаковым именем) и не должно содержать следующие символы:
* \ : { } [ ] | ; < > ? ` ~
* А также не должно содержать непечатаемых символов */
var newTextNoteType = existingTextNoteType.Duplicate("MyNewTextNoteType");
if (newTextNoteType != null)
{
/* Теперь заполним значения основных параметров
* (те параметры, которые отображаются в окне Свойства типа в Revit)
* в том же порядке, в каком они отображаются в окне Свойства типа.
* Я постараюсь подробнее описать значения параметров */
/*Самый сложный параметр – это цвет. Цвет задается в виде целого
* числа и те, кто с этим еще не сталкивался, не сразу понимают,
* как задать это значение. На самом деле все просто – это число –
* это цвета Windows. Подробностей я не расскажу, так как тема
* цветов сложная и объемная.
* В нашем случае я возьму именованный цвет и конвертирую его в
* целочисленное значение цвета Windows. Для этого потребуется
* добавить ссылку на библиотеку System.Drawings */
System.Drawing.Color color = System.Drawing.Color.DodgerBlue;
newTextNoteType.get_Parameter(BuiltInParameter.LINE_COLOR).Set(ColorTranslator.ToWin32(color));
/* Вес линии задается как целочисленное значение и соответствует
* номеру в окне Вес линий. В примере я задаю 1, но если вам нужно
* другое значение, то вы должны следить за тем, чтобы
* не задать номера, отсутствующего в документе */
newTextNoteType.get_Parameter(BuiltInParameter.LINE_PEN).Set(1);
// С задним планом все просто: 0 – непрозрачный, 1 - прозрачный
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_BACKGROUND).Set(1);
// Показать границу: 0 – нет, 1 - да
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_BOX_VISIBILITY).Set(1);
/* Смещение выноски/границы задается в футах (независимо от того,
* в каких единицах отображается в окне Свойства типа). Чтобы не забивать
* себе голову переводом единиц, воспользуемся классом UnitUtils.
* (Хотя я и задаю значение 0.0 все равно советую использовать
* конвертер, чтобы при последующем использовании случайно не задать неверное значение) */
newTextNoteType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET)
.Set(UnitUtils.ConvertToInternalUnits(0.0, DisplayUnitType.DUT_MILLIMETERS));
/* Стрелка выноски задается в виде ElementId. Т.е. нужно в документе
* найти все имеющиеся засечки (Element Type) и у требуемой засечки
* получить Id. В контексте данной темы я не рассматриваю варианты
* поиска засечек и просто подам значение «нет»*/
newTextNoteType.get_Parameter(BuiltInParameter.LEADER_ARROWHEAD).Set(ElementId.InvalidElementId);
/*Шрифт текста – значение параметра задается как обычная строка и
* должно соответствовать имени шрифта, имеющегося в системе.
* Предположительно, чувствительно к регистру. Я не проводил
* экспериментов, устанавливая неверное значение. Как получить список
* шрифтов в системе можете прочитать тут -
* https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/how-to-enumerate-system-fonts */
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set("Arial Black");
// Размер текста также хранится в футах. В примере я задаю размер в миллиметрах
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE)
.Set(UnitUtils.ConvertToInternalUnits(3.0, DisplayUnitType.DUT_MILLIMETERS));
// Для отступа также, как и для размера текста
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_TAB_SIZE)
.Set(UnitUtils.ConvertToInternalUnits(10.0, DisplayUnitType.DUT_MILLIMETERS));
// Значения параметров «Жирный», «Курсив» и «Подчеркнутый»
// задаются как целое число: 0 – нет, 1 - да
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_BOLD).Set(0);
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_ITALIC).Set(1);
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_UNDERLINE).Set(1);
// Коэффициент ширины задается как число с плавающей
// запятой (double) и принимает значение от 0.1 до 10.0
newTextNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(1.0);
}
tr.Commit();
}
return Result.Succeeded;
}
}
}