30 декабря, 2013

Формы и элементы управления.

В этой статье поговорим немного о формах и элементах управления (контролах).
Диалоги большинства параметрических объектов в СПДС оформлены как UniDialog.
UniDialog : функция вызова диалога редактирования объекта.

UniDialog ( [DBFLD, D, Dn, ... ,] [DBINF, Number,Seria,...,]
 [VFLD, rA, "A", rB, "B", ... ,]
 [BFLD, bKey1, "Ключ1", bKey2, "Ключ2",... ,]
 [RADIO, rKey1, "Вариант1", "Вариант2", ... ,]
 [VIDS, strDesignName, "Design1","Design2", ... ,]
 [TVIDS, lVidType, {"F", "T", "R", "L", "All"},]
 [VIEW, {"Vids", "Hdr", "None"}])
В справке по СПДС и MechWizard достаточно подробно описаны ключевые слова и способы вызова стандартного диалога.
Как правило, стандартный диалог состоит из двух вкладок:

«Табличные параметры»,
«Свойства»
Преимуществом такого интерфейса является, только, то, что он может быть полностью описан в методе OnDialog, например так:
function OnDialog {
 LoadInCache( Py, Dy, R, dr, n );
 UniDialog( 
  DBFLD, Py, Dy, R, 
  VFLD, a,@MCS_STRING38,
  VIDS,strDesignName,"All",
  TVIDS,lViewType,"All",
  VIEW,"Vids"
 )
}
Форма создается автоматически время на написание скрипта экономится значительно. Такой подход оправдан при разработке большого количества однотипных параметрических объектов с минимумом выбираемых параметров.
Однако с точки зрения конструктора-проектировщика это не совсем удобно: во первых, после выбора табличного параметра необходимо переключаться на вкладку свойств и там выбирать дополнительные параметры, виды, либо вводить значения в ручную, во вторых построение унифицированного интерфейса предполагает «примитивность» параметрического объекта как, следствие большое количество этих объектов в базе и необходимость их поиска. Пользовательская форма так же загружается методом:
function OnDialog {
 LoadInCache( Obl_prim_sokr, PN, DN, Oboz_tipa_R, DNf, La, D2, n, h4); // загрузка табличных данных из кэша
 ShowForm("Form1"); // вызов пользовательской формы
}
В редакторе объектов это выглядит вот так:
Создание пользовательской формы несколько дольше, чем универсальной , но за счет более интерактивного взаимодействия с пользователем это оправдано. На разработку параметрического объекта времени затрачивается, немного больше один раз, но потом оно многократно экономится, при вставке этого объекта на чертеж.
Вставка и настройка контролов достаточно подробно описаны в справке.
Здесь я хочу рассказать о том, чего в справке нет:
Контролу в свойствах можно сопоставить переменную и потом работать с ней:
Но можно из скрипта напрямую обращаться к контролу:
Если имя форме в свойствах не задано.
 StartSection=Form.editbox; //переменной StartSection присваиваем значение editbox
 StartSection=Form.editbox.Value; // Справедливо и так
Не путать имя формы в ее свойствах и имя формы в редакторе объектов, это разные имена. По имени формы в редакторе объектов вызывается форма
ShowForm("Form1");
Через имя формы в свойствах идет обращение к контролам этой формы:
Если имя форме задано то вместо Form подставляем имя формы на которой вставлен контрол, в данном примере имя формы MyForm:
Очевидно, что если форма всего одна, то имя ей в свойствах можно не присваивать и обращаться к контролам, как в примере выше, если форм несколько, то при совпадении имен контролов на разных формах (на одной форме одинаково назвать не позволит редактор) необходимо обращаться как ниже: с именем формы.
 StartSection= MyForm.editbox; // переменной StartSection присваиваем значение editbox
 StartSection= MyForm.editbox.Value;
//Наоборот
 MyForm.editbox= StartSection; // Контролам можно присваивать значения из переменных:
 MyForm.editbox= MyForm.editbox1; //и из других контролов напрямую, минуя переменную
Присвоение значений объектам формы имеет смысл лишь в методе:
function OnDialogChanged { //метод вызывается при каждом изменении формы
 Form.editbox.Value="Текст в форме";
}
т.к. иначе мы просто не увидим изменений.
Из скрипта можно не только менять свойство Value контрола, но и управлять его видимостью свойство Visible ( значения:FALSE, TRUE или 0, 1).
Контролам полезно давать похожие имена отличающиеся лишь числовым индексом. Допустим на форме у нас имеется семь рисунков друг под другом, и по условию необходимо показать один из них, назовем их image1…. image7
function OnDialogChanged {
// гасим все картинки 
 ii=1 ;
 While (ii<=7){
  Form.image[ii].Visible=FALSE;
  ii=ii+1;
 }
//включаем картинки фланцев в зависимоти от индекса исполнения
 SelectInCache(1,"kFirst", "FlanecKoment", "~", strFlanecKoment); //выбор из базы индекса N_Isp от 1 до 7 
 Form.image[N_Isp].Visible=TRUE; //включаем нужную картинку
}
Порой для того, что бы исключить ввод данных, но оставить возможность пользователю видеть значение контрола необходимо запретить/разрешить возможность редактирования, свойство Enabled (FALSE, TRUE).
function OnDialogChanged {
//По любому изменению в форме мы присваиваем табличные параметры полям ввода: 
//(если включен флажок "Брать атрибуты из базы данных"
 ii=1 ;
 While (ii<=12){
  Form.editbox[ii].Enabled=TRUE; // разрешаем редактирование
  ii=ii+1;
 }
 if (uiStandardParam)==1{ // Если флажок включен
  ii=1 ;
  While (ii<=12){
   Form.editbox[ii].Enabled=FALSE; // запрещаем редактирование
   ii=ii+1; 
  }
  sName=sdbName; // заполняем контролы табличными данными
  sType=sdbType;
  sCode=sdbCode;
  sProducer=sdbProducer;
  sUnits=sdbUnits;
  sMass1=sdbMass1;
  sComment=sdbComment;
  sCategory=sdbCategory;
  sName2=sdbName2;
  sLength=sdbLength;
  sWidth=sdbWidth;
  sHeight=sdbHeight;
 }
}
В данной статье освещены далеко не все возможности управления контролами, в дальнейшем я надеюсь продолжить эту тему.

2 комментария :

  1. Андрей, привет!
    А не подскажешь, можно сделать ручку для отзеркаливания детали?

    ОтветитьУдалить
    Ответы
    1. Если по быстрому:
      В мастере объектов, заходишь в описание этого объекта и в свойстве
      "Класс" ставишь число, либо 680 это двери (SPDSDOOR), или 670 это окна (SPDSWINDOW)
      В объекте появятся ручки зеркалирования по Х и У, но мне не нравится этот способ:
      объект перестанет перекрывать другие объекты независимо от rZOrder;
      не сможет конектиться к другим объектам....
      и возможно пропадут дугие функции.
      Более правильный способ по моему мнению: немного поправить методы SetGripPoint, OnMoveGripPoint и OnChangeParameters, тогда будет зеркалировать.

      Удалить