Создание нестандартных редакторов особенностей
Бывают ситуации, когда редактируемые данные имеют формат, который необходимо обработать нестандартным образом. Выше были перечислены стандартные редакторы особенностей. Может оказаться, что среди них не окажется такого, который мог бы обработать данные специального вида. В этом случае можно пойти двумя путями. Первый - обработать эти данные с помощью специальной формы; второй - создать редактор с наиболее удобным элементов управления. Рассмотрим подробнее оба способа.
Первый способ наиболее простой. В начале необходимо определиться с формой. Здесь возможны два варианта: или создать форму в DesignTime или в RunTime. Обработка формы будет происходить внутри специальной процедуры типа TExecutor, которую затем необходимо будет зарегистрировать:
const dtSample = 100; ... procedure function SampleExecutor(Code, Info: string; var Changed: Boolean; ReadMode: Boolean = False): string; ... implementation ... procedure function SampleExecutor(Code, Info: string; var Changed: Boolean; ReadMode: Boolean = False): string; var SampleForm: TSampleForm; {или TForm, если в RunTime} begin Changed := False; SampleForm := TSampleForm.Create(nil); with SampleForm do begin ... end; procedure TForm1.FormCreate(Sender: TObject); begin RegisterData(dtSample, TButtonEditor, SampleExecutor); ... end; ... end; Не следует регистрировать новый тип данных в конструкторе элемента управления!!! При создании второго экземпляра элемента возникнет ошибка регистрации ERegister (так как это будет попытка зарегистрировать ещё раз на один и тот же номер).
Теперь можно этот новый тип использовать: function TSampleControl.GetParticuls: TParticulList; var P: TParticul; begin ... P := DoProperty('Новый тип', dtSample, ...); ... end; Но иногда хочется обработать новые данные более красивым способом. Тогда можно пойти вторым способом - создать собственный редактор свойств. Как я уже упоминал, не все элементы управления подходят для создания собственного редактора, так, например, трудно будет что-либо редактировать в TStringGrid'е стандартной высотой 20 пикселов!
Перед написанием собственного редактора необходимо выбрать элемент управления, который отобразится в рабочей области Инспектора. Это может быть либо один из элементов управления VCL, обязательно наследник TWinControl (так, например, TSpeedButton не подойдёт!), либо собственный созданный элемент управления, наследник TWinControl (TCustomControl). В конструкторе редактора необходимо инициализировать этот элемент процедурой Init, без инициализации возникнет EAccessViolation. Новый редактор, естественно, должен быть наследником TParticulEditor.
TMyControl = class(TCustomControl) ... TSampleEditor = class(TParticulEditor) ... constructor TSampleEditor.Create; begin inherited Create; Init(TMyControl); ... end; Далее в конструкторе должны быть сделаны необходимые установки: стиль, границы (если необходимо) и, главное, назначены процедуры-обработчики событий для редактирования новой особенности. Так, например, изменение особенности в TEditEditor'е и TComboBoxEditor'е осуществляет OnChange, в TButtonEditor'е и TCheckBoxEditor'е - OnClick. Обработчик будет выглядеть примерно таким образом: procedure TSampleEditor.SelfAction; var Changed: Boolean; begin Changed := True; if Assigned(Executor) then FParticul.Code := Executor((Control as TMyControl).TextProperty, FParticul.Info, Changed, FParticul.ReadMode); if Changed then Make; end; ... constructor TSampleEditor.Create; begin ... (Control as TMyControl).OnAction := SelfAction; end; Желательно, чтобы текстовые данные могли отображаться в Инспекторе при редактировании (например, в TEdit - свойство Text, в TButton, TCheckBox - Caption, в TComboBox реализовано неявно, но, тем не менее, информация о данных выдаётся в Инспектор через Items и ItemIndex), хотя и необязательно.
Также необходимо перекрыть метод SetParticul, который влияет на внешний вид элемента управления в зависимости от значений полей TParticul. Далее необходимо написать специальную процедуру обработки данных. Если это простое присваивание, то можно процедуру не писать (указать при регистрации nil). Новый редактор регистрируется: procedure RegisterData(dtSample, TSampleEditor, SampleExecutor); или procedure RegisterData(dtSample, TSampleEditor, nil); В примере Example2 показаны оба подхода. Нестандартный тип данных THomo обрабатывается c помощью процедуры HomoExecutor, в которой данные редактируются с помощью формы THomoForm2. Для типа данных TDate создаётся новый редактор TDateTimePickerEditor на базе элемента управления TDateTimePicker из VCL.