One of the curious aspects of Delphi is that it is a mature product that many of its users have been working with for a long time. One interesting aspect of this is that most books published about Delphi in the last 10 years assume that the reader is already familiar Delphi. As a result, features in the product that were introduced early in the product's lifecycle are rarely mentioned.
What this means is that there are many features of Delphi that even seasoned Delphi developers may not know about. One of these features is component templates, and permit me to take a few moments of your time to discuss this interesting feature, which has been in the product since Delphi 3.
Overview of Component Templates
A component template consists of one or more components, saved as a group, and added to a page of the Tool Palette, making this collection easy to reproduce. Importantly, any changes that you made to published properties are also saved when you save a component template, permitting you to effortlessly reproduce the particular configuration of the components that make up the template, and this extends to any event handlers that you defined for the components.
While component templates can be useful in a number of situations, they are not a replacement for traditional component development. This article discusses how to create component templates, how to use them, and when you should forgo them in preference for true objects.
You create a component template by selecting one or more components that you have placed onto a form, and then selecting Component | Create Component Template. Delphi responds by displaying the Component Template Information dialog box shown in Figure 1.
Figure 1 The Component Template Information dialog box
You use this dialog box to enter the name of the template, choose which page of the component palette you want it to appear on, and optionally define a custom bitmap that will represent the component on that page.
Once you have created a component template, you can quickly duplicate the components that make up the template by selecting the icon representing the component template from the component palette, and dropping it onto a form or data module. The components placed onto the form duplicate the relative positions of the original objects, as well as any design-time properties and event handlers assigned to them.
Component templates are similar to the templates that appear in the Object Repository. The templates in the repository, however, must be based on a module, such as a form or data module. Due to this, the Object Repository is not well suited for small groups of related components that will normally appear in a container with other components.
Creating a Component Template
The following example demonstrates how to create a component template that has the basic elements for displaying data in a DBGrid:
1. Begin by creating a new form. This form can be associated with an existing project, or you can create it as a form outside of a project (since it will ultimately be discarded at the end of the example anyway).
2. With this form, begin by adding a Panel from the Standard page of the component palette. Set the Panel’s BevelOuter property to bvNone and its Align property to alClient.
3. Next, from the Data Controls page, add a DBNavigator and a DBGrid to the panel. Make sure to add these controls to the inside of the panel. If you accidentally place these controls outside of the panel, delete them and then add then again, making sure that you click inside
the panel.
4. Once these controls are placed, set the DBNavigator’s Align property to alTop and the DBGrid’s Align property to alClient. As long as these controls are within the Panel, the will align within the Panel, rather than with respect to the Form itself.
5. Next, add a DataSource and a ClientDataSet to the form. Set the DataSource’s DataSet property to the ClientDataSet, and both the DBNavigator’s and the DBGrid’s DataSource properties to the DataSource. Your form should look like Figure 2.

Figure 2. Components that are about to become a component template
6. You are now ready to save these components and their properties as a template. Select Edit | Select All to select all of the components on the form. Next, select Component | Create Component Template to display the Component Template Information dialog box. At Component Name, enter TClientDataSetPanel. Click OK to save the template.
To demonstrate the use of this new template, close the form with which you were working. (It is not necessary to save this form since you will recreate all the work from the template.)
Next, select File | New | VCL Forms Application - Delphi to create a new application. Go to the Templates page of the Tool Palette, select the TClientDataSetPanel component, and drop it onto the new project’s main form. All the components that were part of the template are placed on your form. Furthermore, the properties you set at runtime are already defined for these objects. To turn this form into a usable table view, set the Filename property of ClientDataSet1 to the customer.xml file, which is located in a directory with a name similar to C:\Program Files\Common Files\CodeGear Shared\Data.
Creating Component Templates with Event Handlers
While the preceding example demonstrated the ease with which you can create customized sets of components, it did not demonstrate all of the power of this technique. Specifically, this example did not include any event handlers associated with the components. The following example demonstrates how to save a group of components that rely on an event handler to operate properly.
In this example you will create a date range component, one that permits a user to enter a beginning and an ending range of dates. What’s more, this component will include the code necessary to validate the dates entered. This component is design to be placed on a modal dialog box.
1. Begin by creating a new form. Like the preceding example, this form can be associated with an existing project, or it can be a stand-alone form.
2. Next, place onto this form the following components from the Standard page of the component palette: two Labels, two Edits, and two Buttons.
3. With these components in place, you will now need to adjust properties. Set the Caption property of Label1 to Beginning Date and the Caption property of Label2 to Ending Date. Next, set the Text property of both of the Edits to a single blank space. (Do not merely set the Text property to an empty string. Instead, press the Spacebar at least once.)
4. The Buttons are next. Set the Caption property of Button2 to &Cancel and the ModalResult property to mrCancel. Next, set the Caption property of Button1 to &OK. The basic form should look something like that shown in Figure 3.
Figure 3 Creating a component template with event handlers
5. Unlike Button2, whose behavior is controlled by the ModalResult property, you should not set the ModalResult property of Button1. The behavior that this button exhibits must be defined using an event handler. To do this, double-click Button1 to create an OnClick event handler for it. Enter the following code into the generated event handler so that when you are done it looks like the following:
procedure TForm1.Button1Click(Sender: TObject);
var
bd, ed: TDateTime;
begin
bd := StrToDate(Edit1.Text);
ed := StrToDate(Edit2.Text);
if bd > ed then
raise Exception.Create('Beginning date cannot be later '+
'than ending date');
Self.ModalResult := mrOK;
end;
6. Finally, save the new component template. Begin by saving the project. Next, select Edit | Select All to select all of the components, and then select Component | Create Component Template.
7. In the Component Template Information dialog box, set Component Name to TDateRange, and then click OK.
8. To test the new template, create a new project. Add a second form to the project by selecting File | New | Form. On the newly created Form2, add the TDateRange template.
9. Return now to Form1, add a Button, and then add the following event handler to the button’s OnClick event handler:
procedure TForm1.Button1Click(Sender: TObject);
begin
if Form2.ShowModal = mrOK then
ShowMessage('Beginning date = '+Form2.Edit1.Text+
', Ending date = '+Form2.Edit2.Text)
else
ShowMessage('Form2 was cancelled');
end;
10. Finally, add Unit2 to Unit1’s uses clause by selecting File | Use Unit, and then double-clicking Unit2 on the Use Unit dialog box.
Now run the form. Click the button to display Form2 with the date range template on it. Enter a valid date range and then click OK. Form1 displays the entered date range. Now click the button again, and enter an invalid value in one of the date fields. Clicking OK displays the exception dialog box.
The code added to the component template was stored with the template. This code, however, makes use of explicit references to objects that are part of the template. Specifically, in the TDateRange template, the saved code refers to Edit1 and Edit2. What happens when the form on which you place the template already has an Edit1 or Edit2 component on it? The answer is that the components of the template are renamed, and the code in the template is updated.
You can easily demonstrate this effect by following these steps:
1. Close the application you ran in the preceding example.
2. Add a new form to the project by selecting File | New | Form – Delphi.
3. Add a single Edit control to this new form. This control will be named Edit1.
4. Add a TDateRange component template to this form.
Delphi renames the Edit1 and Edit2 components on the template to Edit2 and Edit3. Furthermore, it modifies the code attached to Button1.
Deleting Component Templates
Component templates, which are stored in the file DELPHI32.DCT in Delphi’s BIN directory, can easily be deleted. To delete a component template, open the Templates category from the Tool Palette and then right-click. The displayed context menu will include one delete menu item you can use to delete the entire template category. If you right-click one of the templates in the template category, the menu will include an item you can use to delete that specific template.
Component Template Guidelines
While component templates are an important tool for rapid application development in Delphi, they can be overused. The following are a few guidelines that can help you to better use component templates:
● Try to avoid dependencies on components not part of the template. For example, you might want to create a template for a RichEdit toolbar, without the RichEdit control being part of the template. This toolbar template, however, requires that a RichEdit component be present in order to compile properly. If you must create dependent templates, be sure to add comments to the code references in the template's event handlers indicating which other objects are required by the template, and what these components must be named.
● If you use a particular component template a lot, consider turning it into a custom component. Templates do not support inheritance, whereas true components do.
● Only published properties can be saved as part of a component template. If your component must set properties that are not published, you will need to create a true component.
About the Author
Cary Jensen is the bestselling author of more than 20 books on software development and winner of the 2002 and 2003 Delphi Informant Reader's Choice Award for Best Training. A frequent speaker at conferences, workshops, and seminars throughout much of the world, he is widely regarded for his self-effacing humor and practical approaches to complex issues. Cary's company web site is at: http://www.JensenDataSystems.com. Cary has a Ph.D. from Rice University in Human Factors Psychology, specializing in human-computer interaction.