Fabrizio
Fabrizio

Reputation: 8043

How to properly define a TCustomFrame's child class?

I'm trying to define a child class of TCustomFrame but I get an error on TabOrder property.

These are steps I've followed:

  1. Add a new TFrame descendant to the form (Right click on project, add new, other, frame). enter image description here
  2. Switch the parent class from TFrame to TCustomFrame.

    TMyFrame = class(TCustomFrame)

  3. Check TFrame definition and publish exactly the same properties (Doing so, TMyFrame should be identical to TFrame, right?).

  4. Save and close.
  5. Open unit in which TMyFrame is defined.

It gets an error which says that TabOrder property does not exist. enter image description here

Could someone clarify what's wrong in what I did and how to properly create a TCustomFrame's child class?

Upvotes: 3

Views: 236

Answers (2)

Sertac Akyuz
Sertac Akyuz

Reputation: 54802

What matters is that the published property exists in the design-time package that the component resides in for the IDE to be able to stream it.

When you add a frame to your project, the corresponding 'dfm' file includes properties published in the TFrame class. That includes TabOrder and others. When you close and re-open the project it cannot find TabOrder in TCustomFrame, hence the error.

To be able to explain with a more common component, add a form to your project. Add a published property to your form. Save the project, close and re-open. You won't see your published property in the object inspector. If the IDE would try to stream your property, it would give an error.

For proper operation, what you need to do is to register your component in the tool palette. You need to compile it in a package for that because you won't be able to use "add to palette" shortcut on a TCustomFrame. See documentation for details about how to achieve that. You can start with a unit containing a TFrame descendant for convenience, but don't forget to manually delete (Alt+F12) the properties you un-publish after you've changed the ascendant before saving your unit.

Upvotes: 0

MartynA
MartynA

Reputation: 30715

You seem to be overcomplicating this a bit, and I'm not sure why you think you need your step 2.

The following works fine for me:

  1. Starting with no project open, create a new frame, stick a component or two on it (I just used a TListBox), rename it as MyFrame and save it.

  2. Right click on the frame, select "Add to palette" from the context menu, complete the ensuing dialog to specify which palette page it should appear on and save again. By default it will call it something like "MyFrameTemplate".

  3. Do a "Close All" then start a new project. Navigate to the palette page you specified in step 2 and add an instance of TMyFrame to the form as you would any other component. You will be prompted to add the frame's unit to your project. That's all you should need to do. Fin.

The above works at least as far back as D7, and in Seattle.

If you rename your frame's DFM file and then try to re-open a project that uses it, the IDE will complain that it can't open the DFM and then that it is unable to find the class TMyFrame and ask whether it should be removed from your form. So, use of the frame depends on the existence of its DFM, and since the properties of the components on the frame have already been streamed into its DFM, its difficult to see how you could prevent them being changed in a form which uses the frame, because you would need to defeat the usual steaming mechanism. Perhaps someone knows a cunning way to do that, but it seems to me that a TFrame is the wring place to start if that's what you are wanting to do.

Btw, if you want to prevent things being changed as mentioned in your comment, personally I'd do it as a new compound component, using GExpert's "components to code" to generate the code for its constructor.

Upvotes: 2

Related Questions