Delphi component properties
Author: Zou E-mail: zouf.tech@ATechSoft.comHomepage: http: //www.atechsoft.com/people/zouf/
Note: This article discusses the property issues in the user-defined controls in Delphi, and mainly to discuss the properties of the design (in-design), that is, the attributes seen in the Delphi Object Inspector. This article will be described in more detail on how to implement these properties.
Simple properties
People who are familiar with Object Pascal know that to make the control show the properties in the Object Inspector, simply add the corresponding Property to the Publishs of the class. The simplest example will be given below, which will register a simple control in the Standard panel, which only has a custom property (CAPTION: STRING):
...
TA = Class (TwinControl)
Private
FCAPTION: STRING;
Published
Property Caption: String Read Fcaption Write Fcaption;
END;
PROCEDURE register;
...
PROCEDURE register;
Begin
RegisterComponents ('Standard', [TOUTLOOKPNL]);
END;
Object properties
If a class's properties are objects, the following style will be displayed in the Object Inspector.
The property in the figure is: Action is an object property (Type TBaseAction), Delphi automatically identifies the type and direction-compatible object from the current form when designing, and lists in the drop-down list (as shown above) Action1, action2, action3 ...)
The implementation of this attribute and the implementation of the simple attribute are not distinguished, but also defined in the Property in the public:
Property Action: TBaseAction Read Faction Write Faction;
List type properties
The columns attribute in the TListView in Delphi, the columns attribute in DBGRIDs, etc., which are displayed in the Object Inspector:
Click on the "..." button on the right to open the following form:
The user can correct the "Add" new item (Item) in the form when designing.
The essence of this type of attribute is that its value is a collection, and the user can design the specific content in the Collection in the pop-up form.
The following examples describe how to implement this type of properties:
Unit a;
Interface
Uses Classes, Windows, Sysutils, Controls;
Type
TListProps = Class; // This class is a collection type used to indicate the List property.
TA = Class (TwinControl)
Private
FListprops: TListProps;
Published
Property Listprops: TListProps Read flistProps Write flistprops; // list attribute
public
Constructor Create (Aowner: Tcomponent); OVERRIDE; first create a list attribute destructor destroy; override; / / Remember to destroy List properties
END;
Item type in // list, actually a list property is a collection, and the type of Item must inherit from TCOLLECTIONITEM
TListItem = Class (TCOLLECTIONITEM)
Private
FITEM: TWINCONTROL;
public
Procedure assign; override; // Because you need to assume an assignment, you must overload the method to COPY
Published
Property Item: TwinControl Read Fitem Write Fitem; // This is a attribute of TListColumn in the figure above
END;
// List collection class
TListProps = Class (TCOLLECTION)
Private
FOWNER: TPERSISTENT; / / This property is a must, because for the list property, if edited in the pop-up window, you must react to the original control when designing, this property indicates the list property. Owner (OWNER), so that Owner can be notified when the list property is modified, the corresponding adjustment is notified, and it is generally necessary to overload in this class: Procedure Update (item: tcollectionItem); Override; this method
protected
Function Getowner: TPERSISTENT; OVERRIDE;
public
Constructor Create (Aowner: TPERSIStent);
Function Owner: TPERSISTENT;
END;
PROCEDURE register;
IMPLEMENTATION
PROCEDURE register;
Begin
RegisterComponents ('Standard', [TA]);
END;
{TLISTITEM}
Procedure TlistItem.Assign (Source: TPERSIStent);
Begin
inherited;
IF Source Is TlistItem Then
Begin
FITEM: = TLISTITEM (SOURCE) .fitem;
end
Else Inherited Assign (Source);
END;
{TListProps}
Constructor TListProps.create (Aowner: TPERSIStent);
Begin
Inherited Create (TLISTITEM);
FOWNER: = aowner;
END;
Function TListProps.getowner: TPERSISTENT;
Begin
Result: = FOWNER;
END;
Function TListProps.owner: TPERSISTENT;
Begin
Result: = FOWNER;
END;
{Ta}
Constructor TA.CREATE (Aowner: Tcomponent);
Begin
inherited;
FListprops: = TListProps.create (Self);
DEStructor TA.DESTROY;
Begin
Freeandnil (FlistProps);
inherited;
END;
End.
The understanding of other parts is very simple, here is the implementation of the collection of TListProps, including the implementation strategies of Owner, Update, etc. It is necessary to understand.
Of course, this is just a basic framework. The actual control may also need to add something.
Custom attribute
There is also the last type of "attribute", which is different from the previous attributes, generally appearing in the following: Right-click in the control, there will be an attribute editor in the pop-up menu, as shown in the figure below ... " , Click on the menu item, will
The property editing form appears as shown below:
In fact, this form is a form that the control writer itself provides a form, so how can you bind a form and a control? And make the modification of the value in the form to the attribute value of the control? (In fact, this property is still much, such as TimageList, TtreeView, etc.)
Below below, by an example:
TEDITORFORM: TFORM; // This is an attribute window class
TControl: twinControl; // This is the control class
Suppose these two classes have been written.
EditorForm: TeditorForm;
Control: tcontrol;
It is an example of two classes.
TComponEnteditor is used to implement a clicking action on the control to right-click menu to the Properties window, thereby implementing a different menu item opens a different property window.
It mainly has three methods:
Function GETVERB (INDEX: Integer): String; Override;
It represents the caption value of the Idex menu item on the menu (Customize ...)
Function GETVERBCOUNT: Integer; Override;
It indicates how many menu items have
Procedure Executeverb (Index: Integer); OVERRIDE;
It indicates the operation that is executed when you click on the INDEX menu item.
A sample is given below:
Type
TCONTROLEDITOR = Class (Tcomponiteteditor)
public
Function GETVERB (INDEX: Integer): String; Override;
Function GETVERBCOUNT: Integer; Override;
Procedure Executeverb (Index: Integer); OVERRIDE;
END;
Function TCONTROLDITOR.GETVERB (INDEX: Integer): String;
Begin
Result: = '& Edit Items ...';
END;
Function TCONTROLEDITOR.GETVERBCOUNT: Integer;
Begin
RESULT: = 1;
END;
Procedure tcontroleditor.executeverb (INDEX: Integer);
VAR
DLG: TEDITORM;
Begin
DLG: = TEDITORM.CREATE (APPLICATION);
Try
Dlg.ShowModal;
If DLG.MODALRESULT = MROK THEN
Begin
If DLG.MODIFIED THEN
Begin
CopyProperty (DLG, Component); // assigns the modified attribute to the TESIGNER.MODIFIED;
END;
END;
Finally
Dlg.free;
END;
END;
Finally, to make the mapping between the two controls and properties are performed by the system in design, the call to the RegisterComponEnteditor method must be added to the Register method, as in the following example:
PROCEDURE register;
Begin
RegisterComponiteteditor (TControl, tcontroleditor);
END;
######################################################################################################################################################################################################################################################################################################## ###########################################