![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Здравствуйте.
Стандартная (в каком-то смысле) задача: выбирая очередную запись из combobox меняется интерфейс программы. Аля выбрали в списке "редактирование справочника А", ниже прогрузился фрейм с полями этого справочника. Выбрали редактирование справочника Б - второй фрейм подгрузился. Оба фрейма созданы и упакованы в соответствующие юниты в режиме design-time. Аля модуль обработки данных под названием А привязан к фрейму и его классу TFrameA, а обработка B так же к TFrameB. Оба унаследованы от TFrame Создавая фреймы так же были созданы две функции с одинаковыми именами EditAndSave(): integer, которые выполняют РАЗНЫЕ преобразования с данными на фреймах, но возвращают однотипный результат в виде кода ошибки (статуса) Архитектурно в голове сидит мысль о том, что надо завести переменную, в которой я буду хранить экземпляр текущего активного фрейма, и обращаясь через неё к функции. НО! Во-первых, какой тип этой переменной должен быть? Ведь фреймы разных классов. Один от TFrameA, второй от TFrameB. Во-вторых, функция имея одно и тоже название должна быть ... virtual? abstract? overload? Найдутся тут сеньёоры, понимающие весь этот глубокий мир ООП? Последний раз редактировалось Uniq!, 25.05.2023 в 23:10. |
|
#2
|
|||
|
|||
|
Думаешь в правильном направлении. У этих фреймов должен быть общий предок, в котором данная фунция должна быть virtual; abstract;
Код:
unit frmEditFrameBase;
type
TEditFrameBase = class(TFrame)
...
public
function EditAndSave() : Boolean; virtual; abstract;Код:
unit frmEditFrameA;
uses frmEditFrameBase;
type
TEditFrameA = class(TEditFrameBase)
...
public
function EditAndSave() : Boolean; override;
...
function TEditFrameA.EditAndSave() : Boolean;
begin
// Do for FrameA
// Do not call inherited here due to this method is abstract in the parent
end;Код:
unit frmEditFrameB;
uses frmEditFrameBase;
type
TEditFrameB = class(TEditFrameBase)
...
public
function EditAndSave() : Boolean; override;
...
function TEditFrameB.EditAndSave() : Boolean;
begin
// Do for FrameB
// Do not call inherited here due to this method is abstract in the parent
end;Код:
var myFrame : TEditFrameBase; begin myFrame := TEditFrameA.Create(Nil); myFrame.EditAndSave; myFrame.Free; ... myFrame := TEditFrameB.Create(Nil); myFrame.EditAndSave; myFrame.Free; PS. Для того, что бы не мучаться с ручным редактированием предка для фрейма (а его надо указать и в .pas и в .dfm файлах), есть визуальное наследование. Когда создаешь новую форму/фрейм, там в диалоге есть раздел с именем твоего приложения, в нем все формы и фреймы, которые ты уже создал. Просто кликаешь на нужной форме/фрейме и Delphi сама отнаследует от выбраного элемента. Кстати, так и контролы будут наследоваться, так что если у тебя на фрейме есть общая часть, ее можно отдизайнить на общем предке и в потомках добавлять только различия. Последний раз редактировалось lmikle, 26.05.2023 в 19:14. |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Uniq! (26.05.2023)
| ||
|
#3
|
||||
|
||||
|
Странное поведение наследуемого фрейма. См изображение с ошибкой.
Видимо IDE не понимает VCL или FMX фрейм я унаследовал у TFrame к своему типу TBaseFrame. В dfm файле при этом все свойства есть, естественно, т.к. сама IDE их же и создаёт. Погуглил. Говорят мол "если вы создавали свой фрейм в более новой версии то... в старой ..." но я создаю всё в одной и той же версии ![]() https://delphisources.ru/forum/attac...d=168548578 9 Код:
object fDateEditFrame: TfDateEditFrame Left = 0 Top = 0 ClientHeight = 201 ClientWidth = 304 Color = clAppWorkSpace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = True PixelsPerInch = 96 TextHeight = 13 Ругается на ClientHeight ClientWidth OldCreateOrder PixelsPerInch TextHeight. Удаляя эти свойства я теряю структуру фрейма) и видимость компонент, зато запускается без ошибок Куда подскажите копать? Последний раз редактировалось Uniq!, 31.05.2023 в 01:34. |
|
#4
|
|||
|
|||
|
А как ты наследуешь?
Перечисли по шагам. |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Uniq! (31.05.2023)
| ||
|
#5
|
||||
|
||||
|
Вчера удалось "завести" путём следующих итераций:
1) New - Other - Frame - именуем его как TBaseFrame 2) Добавляем в его паблик нужное виртуальное абстрактное 3) Создаём ещё два через New - Other - Frame, руками меняю TFrame на TBaseFrame 4) Переопределяем нужное 5) в dfm файлах в первой строчке меняю object на inherited ... 6) Profit А изначально было: вместо 1го пункта, я просто создал unit и в нём определил TBaseFrame. Т.е. у такого варианта не было dfm части. Переспал с проблемой и понял, о чём был ваш комментарий по поводу наследования через IDE, а не руками... Если TBaseFrame создать тоже через IDE со своим dfm, то при создании наследников в п.3 этот TBaseFrame появится в качестве опции для наследования. И inherited в dfm прописывается самостоятельно...Так что в целом вопрос решён.) Спасибо, ещё раз! Последний раз редактировалось Uniq!, 31.05.2023 в 10:30. |
|
#6
|
|||
|
|||
|
Вот!!!
Надо делать правильно ![]() Ну работает - и хорошо. |