Рефакторинг наследования TFrame
Еще один вопрос от зарегистрированного компонента TFrame от меня. Спасибо за помощь, коллеги программисты.:)
Играя с предложением Дарриана о наследовании TFrame здесь:
Особенности:
По сути, у меня есть компонент на основе TFrame, который я зарегистрировал в IDE, и он прекрасно работал. Сейчас я занимаюсь разработкой нескольких "сестринских" компонентов, которые будут в значительной степени разделять невизуальную функциональность и свойства существующего компонента. Поэтому имеет смысл перенести большую часть этого в родительский / суперкласс, от которого могут наследоваться как новый, так и старый компоненты.
Каков наилучший способ "рефакторинга" наследования TFrame таким способом? (Это может относиться и к потомкам класса TForm, не уверен). На какие предостережения и вещи стоит обратить внимание?
Пример:
Я пытался, например, создать новый TFrame, на котором ничего нет, и вызвать этот фрейм TMyBaseFrame. Затем изменил определение класса моего существующего компонента (назовем его TMyFrameTreeView), чтобы наследовать от него, а не от TFrame.
Он скомпилировался нормально, но когда я попытался сбросить его в форму, я получил "ClientHeight not found" (или "свойство ClientHeight not found"), и оно не выпало в форму. Удаление ClientHeight и ClientWidth из соответствующего DFM привело к хаосу, и они все равно были заменены при изменении размера. Я заметил ExplicitHeight и ExplicitWidth в дочерних классах, и я думаю, что это связано с переопределением значения свойства из унаследованных значений, но я не уверен. Воссоздание совершенно нового фрейма с помощью New -> Inherited Items, а затем копирование всего, также не дало больших результатов.
Финальная нота
Я понимаю, что это может быстро запутаться, с потоковой передачей файлов DFM и несколькими поколениями потомков и т. Д..... что является частью того, почему я прошу общий концептуальный аспект "вещи, которые нужно искать", но также и конкретный более простая и реальная версия проблемы (которая, на мой взгляд, должна быть выполнимой).
Я создал небольшой тестовый пакет, чтобы разбираться в попытках обучения, и я многому учусь, но он медленный, и любое руководство / понимание от вас, Delphi, "Мастера джедаев", было бы очень признательно.:)
Ответ обновлю позже:
Оба ответа ниже были полезны. Кроме того, создание "Базового класса кадра", в котором НЕТ изменений по сравнению с обычным TFrame, и ТО, что наследование от него до добавления каких-либо свойств, методов и т. Д., По-видимому, значительно стабилизирует потоковую передачу наследования. Не уверен, почему, но пока так и есть.
2 ответа
В дополнение к изменению базового класса TMyFrameTreeView
в TMyBaseFrame
измените первое слово в файле dfm на TMyFrameTreeView
от object
в inherited
,
Сейчас я занимаюсь разработкой нескольких "сестринских" компонентов, которые будут в значительной степени разделять невизуальную функциональность и свойства существующего компонента. Поэтому имеет смысл перенести большую часть этого в родительский / суперкласс, от которого могут наследоваться как новый, так и старый компоненты.
Каков наилучший способ "рефакторинга" наследования TFrame таким способом?
Суть вашего текста выше, возможно, заключается в " невизуальной функциональности компонента". Так что, в этом случае, ИМХО, лучше разделить визуальный и невизуальный слои.
Итак, возможно, лучше использовать декоратор:
TMySharedEngine = class(Whatever)
property LinkedFrame: TFrame;
property P1;
property P2;
...
procedure Proc1;
procedure Proc2;
... //etc.
end;
и в ваших "сестринских" кадрах использовать экземпляры этого:
var
TMyFrame1 = class(TFrame)
...
FDecorator: TMySharedEngine;
...
public
property MySharedPart: TMySharedEngine read FDecorator;
constructor Create(AOwner: TComponent); override;
...
end;
constructor TMyFrame1.(AOwner: TComponent); override;
begin
inherited;
FDecorator:=TMySharedEngine.Create; //ok, ok do not forget to Free it .Destroy
FDecorator.LinkedFrame:=Self;
...
end;
OTOH, если вы хотите использовать свой подход, вы можете использовать Visual Form Inheritance (как предложил Darian) или (более гибко) вы можете сделать это вручную: создайте с помощью IDE следующие фреймы: TBaseFrame, TChildFrame1, TChildFrame2 ... и т. Д. Теперь перейдите к модулю TChildFrame1 и вручную измените его определение класса с TChildFrame1 = class(TFrame) на TChildFrame1 = class(TBaseFrame). Компиляция. Он должен работать. Тем не менее, рекомендуется, чтобы при выполнении этого трюка TBaseFrame был пустым, чтобы избежать возможных мелких причуд (коллизии функций и т. Д.)
НТН.