Рефакторинг наследования TFrame

Еще один вопрос о зарегистрированном компоненте TFrame IDE от меня. Спасибо за помощь, друзья-программисты. :)

Поиграйте с предложением Дарриана наследования TFrame здесь :

Особенности:

По сути, у меня есть компонент на основе TFrame, который я зарегистрировал в IDE, и он отлично работает. Сейчас я разрабатываю несколько «сестринских» компонентов, которые будут разделять большую часть невизуальных функций и свойств существующих компонентов. Таким образом, имеет смысл перенести большую часть этого в родительский / суперкласс, от которого могут наследовать как новые, так и старые компоненты.

Как лучше всего «реорганизовать» наследование TFrame таким образом? (Это может относиться и к потомкам класса TForm, не уверен). Какие предостережения и чего следует остерегаться?

Пример:

Я попытался, например, создать новый TFrame, на котором ничего не было, и вызвать этот кадр TMyBaseFrame. Затем изменил определение класса моего существующего компонента (назовем его TMyFrameTreeView), чтобы наследовать от него, а не от TFrame.

Он скомпилировался нормально, но когда я попытался отбросить его в форму, я получил «ClientHeight not found» (или «Свойство ClientHeight не найдено»), и оно не пропало в форме. Удаление ClientHeight и ClientWidth из соответствующего DFM нанесло ущерб, и в конечном итоге они были заменены при изменении размера. Я заметил ExplicitHeight и ExplicitWidth в дочерних классах и думаю, что это связано с переопределением значений свойств из унаследованных значений, но я не уверен. Воссоздание совершенно нового кадра через New -> Inherited Items с последующим копированием всего заново тоже не дало хороших результатов.

Заключительное примечание

Я понимаю, что это может быстро стать беспорядочным из-за потоковой передачи файлов DFM и нескольких поколений потомков и т.д .... что является частью того, почему я прошу общих концептуальных аспектов, на которые нужно обратить внимание, но также даю конкретный реальная более простая версия проблемы (которая, как мне кажется, должна быть выполнимой).

Я создал небольшой тестовый пакет, чтобы взламывать попытки обучения, и я многому научился, но он медленно продвигается, и любое руководство / понимание от вас, Delphi "Мастера-джедаи", будет НАИБОЛЕЕ оценено. :)



Ответ обновите позже:

Оба ответа ниже были полезны. Кроме того, создание «Базового класса кадра», в котором НЕТ изменений по сравнению с обычным TFrame, и ТОГДА его наследование перед добавлением каких-либо свойств, методов и т. Д., Похоже, значительно стабилизирует наследование потоковой передачи. Не уверен, почему, но пока это так.

Ответов (2)

Решение

В дополнение к изменению базового класса TMyFrameTreeView для TMyBaseFrame изменения первого слова в файле dfm для TMyFrameTreeView from object to 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, если вы хотите использовать свой подход, вы можете использовать наследование визуальной формы (как предложил Дариан) или (более гибкий), вы можете сделать это вручную: Создайте с помощью IDE следующие фреймы: TBaseFrame, TChildFrame1, TChildFrame2 ... и т. Д. Теперь перейдите к модулю TChildFrame1 и вручную измените определение его класса с TChildFrame1 = class (TFrame) на TChildFrame1 = class (TBaseFrame). Скомпилировать. Он должен работать. Однако рекомендуется, чтобы при выполнении этого трюка TBaseFrame был пустым, чтобы избежать возможных мелких причуд (столкновения функций и т. Д.)

HTH.