Принудительное скрытие/показ особенностей
Поле TParticul.Visible, как уже упоминалось, отвечает за "видимость" особенности в рабочей области Инспектора. В основном оно используется "внутри" Инспектора и массива особенностей TParticulList; например, при выделении нескольких объектов редактирования, оно скрывает те общие их особенности, поля Code которых не равны (таким же образом поступает Delphi при выделении нескольких компонентов на форме в DesignTime).
Однако бывают случаи, когда необходимо скрывать или показывать особенности "вручную". Это те случаи, когда при изменении какой-либо особенности, редактируемый объект в корне меняется и желательно скрыть те свойства, которые при этом значении изменённой особенности не только не нужны, но и мешают сориентироваться в ситуации.
Приведу пример из своего опыта, опять же из области САПР. Допустим, есть схема ТСхема, обладающая свойством База: ТБаза, которое принимает значения бзПневматическая, бзКинематическая, бзЭлектронная. Как известно из автоматики, при замене в схеме, скажем, всех электронных элементов и связей на пневматические, логика работы схемы не меняется. Пусть у нас схема имеет свойство База = бзПневматическая. Тогда в ней важны такие параметры, как давление, поток через проводники, ёмкости резервуаров и другие гидравлические параметры. Мы меняем в Инспекторе свойство База на бзЭлектронная. Тогда станут важны другие параметры, такие как напряжение, сила тока, ёмкости конденсаторов и пр. Как в этом случае быть с давлением и потоком? Можно, конечно, их запретить (TParticul.Enabled := False), однако, при этом загромождается рабочая область Инспектора "лишними" в этом случае особенностями, мешающими нормальной работе пользователя. Поэтому, в этом случае лучше их скрыть вообще: function ТСхема.GetParticuls: TParticulList; var P: TParticul; begin ... P := DoProperty('Давление', dtReal, True, База = бзПневматическая, ДавлениеToStr(FДавление), '', False); Add(P); ... end; Приведу другой пример. Пусть у нас редактируется элемент управления, который при редактировании может менять свой класс, например TComboBox, TColorBox и TShellComboBox (у кого нет последних двух компонентов, поясню: TColorBox - комбобокс выбора цвета, TShellComboBox - выбор папки (как в окнах папок Windows 98 сверху)). Все эти компоненты "комбобоксобразные", у них есть общие свойства, но есть и индивидуальные, например общие: Width, Left, DropDownCount и пр., индивидуальные: TComboBox - Items, CharCase; TColorBox - DefaultColor, Selected; TShellComboBox - Root, UseShellImages. type TMultiControl = class(TExternalControl) private FComboBox: TComboBox; FColorBox: TColorBox; FShellComboBox: TShellComboBox; ... end;
Смена элемента управления будет осуществлена так:
... function TMultiControl.GetParticuls: TParticulList; var P: TParticul; L: TStringList; begin ... {в начале запишем в L три строки - названия классов каждого элемента управления (например, FComboBox.ClassName)} P := DoProperty('Класс', dtEnum, True, True, ExternalObject.ClassName, L.CommaText, False); ... end;
Естественно, до этого в конструкторе свойству ExternalObject должно быть присвоено какое-либо из полей (FComboBox, например) и все поля должны быть проинициализированы.
... procedure TMultiControl.SetParticul(Value: TParticul); var SParent: TWinControl; begin ... if Value.Name = 'Класс' then begin SParent := (ExternalObject as TControl).Parent; (ExternalObject as TControl).Parent := nil; if Value.Code = FComboBox.ClassName then ExternalObject := FComboBox else if Value.Code = FColorBox.ClassName then ExternalObject := FColorBox else ExternalObject := FShellComboBox; (ExternalObject as TControl).Parent := SParent; end; ... end; ...
В таком случае обработка частных особенностей будет происходить таким образом:
... function TMultiControl.GetParticuls: TParticulList; var P: TParticul; begin ... P := DoProperty('Цвет по умолчанию', dtColor, True, ExternalObject is TColorBox, ColorToString(FColorBox.Color), '', False); ... end; Обработка в SetParticul происходит обычным способом, так как "защита от несанкционированных действий" уже предусмотрена в GetParticuls.
В примере Example4 продемонстрирована разработка и использование "мультиэлемента".