Delphi 3. Библиотека программиста

       

Пример модели


Хотя файл EMBEDDEDFORMS.PAS прежде всего демонстрирует, как внедренные формы применяются на практике, и предоставляет работоспособную основу для построения мастеров и списков свойств, в нем также присутству ет упрощенная модель данных и четыре вида — как для того, чтобы научить вас пользоваться мастерами, так и в качестве примера внедрения видов друг в друга.

Модуль Data представляет собой «скелет» модуля данных с методами для создания, «загрузки» и «сохранения» объектов Employee (см. листинг 10.10). Вероятно, в реальном приложении эти методы будут представлять собой оболочки для процедур, работающих с базами данных; в нашем случае метод загрузки лишь извлекает «зашитые» в программе фиктивные данные, а метод сохранения вообще ничего не делает. Объект Employee содержит ссылки на два объекта People с личными данными работника и его начальника. Вид Employee View, изображенный на рис. 10.1 и 10.2, позволяет выбрать начальника из раскрывающегося списка, а также отредактировать имя и налоговый код (TaxID) работника.

Самое интересное заключается в том, что для отображения сведений о работнике и начальнике применяется один и тот же вид — для этого создается две различные копии одного объекта вида. В режиме конструирования оба вида выглядят как пустые панели (см. рис. 10.6). При создании формы мы создаем два экземпляра вида PersonIdView (см. листинг 10.7) и размещаем их на соответствующих панелях формы EmployeeIdview.

Рис. 10.6. Вид, одновременно являющийся фреймом

Рис. 10.7. PersonIdView в режиме конструирования

Листинг 10.10. Модуль EMPLOYEEIDVIEWS.PAS

unit EmployeeIdViews; // Copyright © 1997 by Jon Shemitz, //all rights reserved. // Permission is hereby granted to freely use, //modify, and // distribute this source code PROVIDED that //all six lines of // this copyright and contact notice are //included without any // changes. Questions? Comments? Offers of work? // mailto:jon@midnightbeach.com // ---------------------------------------- // Это достаточно правдоподобная реализация вида Employee ID. // Она позволяет вводить имя и налоговый код, а также // указывать начальника. interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Models, Embedded, FickleViews, PersonIdViews; type TEmployeeIdView = class(TFickleView, IFrame) SupervisorPnl: TPanel; SupervisorCaptionPnl: TPanel; SupervisorFrame: TPanel; SelectSupervisor: TComboBox; SupervisorLbl: TLabel; EmployeeIdFrame: TPanel; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure SelectSupervisorChange(Sender: TObject); private SupervisorView, EmployeeView: TPersonIdView; protected procedure ReadFromModel(Model: TModel); override; procedure WriteToModel(Model: TModel); override; procedure SetReadOnly(Value: boolean); override; procedure OnValidChanged( ChangingObject: TObject; View: IView ); end; implementation

{$R *.DFM} uses Data; // Создание/уничтожение procedure TEmployeeIdView.FormCreate(Sender: TObject); var Index: integer; begin inherited; SupervisorView := TPersonIdView.CreateEmbedded( Self, SupervisorFrame, efmCentered ); SupervisorView.ReadOnly := True; SupervisorView.AddNotifiee(Self); EmployeeView := TPersonIdView.CreateEmbedded( Self, EmployeeIdFrame, efmCentered ); EmployeeView.AddNotifiee(Self); with DataModel do for Index := 0 to SupervisorCount - 1 do SelectSupervisor.Items.Add( GetEmployeeName(Supervisor[Index]) ); end; // TEmployeeIdView.FormCreate procedure TEmployeeIdView.FormDestroy(Sender: TObject); begin inherited; SupervisorView.RemoveNotifiee(Self); SupervisorView.Free; EmployeeView.RemoveNotifiee(Self); EmployeeView.Free; end; // TEmployeeIdView.FormDestroy // Переопределения IView procedure TEmployeeIdView.ReadFromModel(Model: TModel); begin Assert(Model is TEmployee); with TEmployee(Model) do begin SupervisorView.ReadFromModel(Supervisor); EmployeeView.ReadFromModel(Employee); SelectSupervisor.ItemIndex := DataModel.IndexOfSupervisor(Supervisor.ID); end; // with end; // TEmployeeIdView.ReadFromModel procedure TEmployeeIdView.WriteToModel(Model: TModel); begin Assert(Model is TEmployee); with TEmployee(Model) do begin SupervisorView.WriteToModel(Supervisor); EmployeeView.WriteToModel(Employee); end; // with end; // TEmployeeIdView.WriteToModel procedure TEmployeeIdView.SetReadOnly(Value: boolean); begin inherited; EmployeeView.ReadOnly := ReadOnly; SelectSupervisor.Color := ShowReadOnly_EditColors[ReadOnly]; end; // TEmployeeIdView.SetReadOnly // Изменение начальника procedure TEmployeeIdView.SelectSupervisorChange (Sender: TObject); var ID: TPersonID; Supervisor: TPerson; begin inherited; ID := DataModel.Supervisor [SelectSupervisor.ItemIndex]; Supervisor := DataModel.LoadPerson(ID); try SupervisorView.ReadFromModel(Supervisor); finally Supervisor.Free; end; end; // TEmployeeIdView.SelectSupervisorChange // Уведомление фрейма procedure TEmployeeIdView.OnValidChanged( ChangingObject: TObject; View: IView ); begin Valid := SupervisorView.Valid and EmployeeView.Valid; end; // TEmployeeIdView.OnValidChanged end.

Процедура FormCreate создает два вида TPersonIDView и регистрируется как их фрейм. Вид начальника доступен только для чтения, однако начальника можно сменить с помощью раскрывающегося списка. FormDestroy отменяет регистрацию (то есть освобождает интерфейсную ссылку) и уничтожает внедренные формы.

ReadFromModel и WriteToModel, в сущности, перепоручают свою работу внедренным видам. Обычно рекомендуется, чтобы все функции ввода/вывода моделей следовали этому примеру и с помощью Assert проверяли, относится ли аргумент-модель к ожидаемому типу. В этом случае при передаче неверного типа модели редактору (или неверного типа вида — процедуре настройки редактора модели) возникает runtime-ошибка.



Содержание раздела