Официальный форум российского программного комплекса T-FLEX PLM


Поиск  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: 1
Не работает блок set свойства TFlex.Model.Model2D.MultilineText.Node
 
Доброго всем здоровья, уважаемые форумчане.

Обнаружил в классе TFlex.Model.Model2D.MultilineText (позволяет управлять многострочным текстом, см. команду TE: Создать текст - Создать многострочный текст<M>) странности при установке свойства Node. Свойству нельзя задать значение, отличное от null. То есть, с помощью API нельзя привязать текст к узлу. Вручную в CAD это, конечно, возможно.
Ниже привожу код тестового макроса. Он был создан с помощью встроенного редактора макросов TFlex CAD. Макрос находится в файле "Тест MultilineText_Node.grb".
Код
using System;
using TFlex.Model;
using TFlex.Model.Model2D;
using System.Windows.Forms;
namespace NewMacroNamespace
{
    public class NewMacroClass
    {
        public static void Привязать_многострочный_текст_к_узлу()
        {
            Document doc = TFlex.Application.ActiveDocument;
            if (doc != null &&
                doc.Selection.GetSize() > 0 &&                //Выбран хотя бы один элемент
                doc.Selection.GetAt(0).GetType() == typeof(MultilineText))    //И это многострочный текст
            {
                if (!doc.IsChanging())
                    doc.BeginChanges("Привязка текста к узлу");
                MultilineText text = (MultilineText)doc.Selection.GetAt(0);    //В условии тип уже проверили
                FreeNode node = new FreeNode(doc, new Parameter(10), new Parameter(20));    //Координаты узла X=10, Y=20
                //Пытаемся привязать текст к только что созданному узлу node
                text.Node = node;
                if (doc.IsChanging())
                    doc.EndChanges();
                //Сообщение в окне всегда будет "Свойство Node выбранного текста: null"
                MessageBox.Show(
                    String.Format("Свойство Node выбранного текста: {0}",
                    text.Node == null ? "null" : text.Node.GetType().FullName));
            }
        }
    }
}
Перед запуском макроса необходимо выбрать многострочный текст на единственной странице.
После выполнения строки
Код
text.Node = node;
свойство Node остаётся null.
В конце работы макрос всегда показывает сообщение "Свойство Node выбранного текста: null".
Для лучшего понимания, что происходит в блоке set, заглянем в недра сборки TFlexAPI с помощью бесплатной утилиты JetBrains dotPeek (https://www.jetbrains.com/decompiler/).
Декомпилированный код блока set свойства TFlex.Model.Model2D.MultilineText.Node:
Код
// Assembly: TFlexAPI, Version=12.0.74.0, Culture=neutral, PublicKeyToken=eab6a180a6be0d77
// Assembly location: C:\Program Files (x86)\T-FLEX\T-FLEX CAD 12\Program\TFlexAPI.dll
/// <summary>
/// Узел привязки текста
/// </summary>
public unsafe Node Node
{
  get
  { ... }
  set
  {
    this.CheckObject((ModelObject) value);
    TFMultilineText* textForSet = this.TextForSet;
    if (value != null)
      return;                                    //от себя: нет никакой реализации для установки свойства
    *(int*) ((IntPtr) textForSet + 236) = -1;    //от себя: выполняется для случая value == null
  }
}
Обратите внимание на строки:
Код
if (value != null)
    return;
Значит, установить свойство Node в не-null невозможно, вместо этого происходит простой возврат из блока set.
Для сравнения привожу аналогичный код для класса LineText. Он позволяет управлять строчным текстом TFlex CAD, см. команду TE: Создать текст - Создать строчный текст<D>.
Блок set для свойства TFlex.Model.Model2D.LineText.Node:
Код
/// <summary>
/// Узел привязки текста
/// </summary>
public unsafe Node Node
{
  get
  { ... }
  set
  {
    this.CheckObject((ModelObject) value);
    if (value == null)
      *(int*) ((IntPtr) this.repSet + 236) = -1;
    else
      *(int*) ((IntPtr) this.repSet + 236) = <Module>.CTFObject.GetIndex((CTFObject*) value.repGet);
  }
Обратите внимание, что здесь обрабатываются оба случая, когда value == null и когда != null. В отличие от MultilineText.Node, свойство LineText.Node и позволяет привязать строчный текст к заданному узлу.
Жду ваших комментариев, уважаемые форумчане.
Надеюсь, что вышеописанный недочёт дойдёт до внимания разработчиков и будет устранён для API TFlex CAD 12.
Файл "Тест MultilineText_Node.grb" прикреплён к сообщению.
Используемая версия CAD: TFlex CAD x32 12.0.74.0
Версия среды выполнения: v4.0.30319
Сборка TFlexAPI, Version=12.0.74.0, Culture=neutral, PublicKeyToken=eab6a180a6be0d77
Операционная система: Windows 7 x64.
 
Попробуйте так...

Код
using TFlex.Model;
using TFlex.Model.Model2D;

namespace Test
{
    public class Class3
    {
        public static void Run()
        {
            Document doc = TFlex.Application.ActiveDocument;
            doc.BeginChanges("Привязка текста к узлу");

            double x = 0.0;
            double y = 0.0;

            foreach (Node node in doc.GetNodes())
            {
                x = node.AbsX;
                y = node.AbsY;

                foreach (MultilineText mtext in doc.GetTexts())
                {
                    if (doc.Selection.IsSelected(mtext))
                    {
                        mtext.X = x;
                        mtext.Y = y;
                        break;
                    }
                }
            }
            doc.EndChanges();  
        }
    }
}
T-FLEX CAD 17.1.6.0
 
Цитата
Николай написал:
Надеюсь, что вышеописанный недочёт дойдёт до внимания разработчиков и будет устранён для API TFlex CAD 12.
Спасибо за сообщение об ошибке.
Исправление войдет в следующие сборки T-FLEX CAD версий 12 и 14.
Страницы: 1