Bob Swart (aka Dr.Bob)
Delphi 5 Property Categoriën

Een paar maanden geleden hebben we de TEuroEdit gezien, een TEdit component met een Euro property. Behalve een Euro property, waar we het huidige saldo van kunnen uitlezen (of een nieuw saldo in kunnen schrijven), kan ik me ook voorstellen dat we Gulden en BFR properties willen hebben. De opslag zou nog steeds in Euro zijn, maar de GetGulden en GetBFR methoden zouden gewoon ter plekke de bekende Euro-conversie uitvoeren.

Waarom deze inleiding? Welnu, ik wil uitkomen op een zinvol voorbeeld voor een nieuwe feature in Delphi 5, namelijk property categories.

Property Categoriën zijn een uitbreiding in het VCL model van Delphi 5 dat eigenlijk alleen in de Object Inspector terug te vinden is. Daar kunnen we nu de properties van componenten (en Forms) zien By Name (zoals we gewend zijn) of By Catgory. Los daarvan, maar met name nuttig voor de laatste van deze twee, kunnen we ook bepaalde property categoriën uitschakelen - dus niet alle properties tegelijk zien (of juist alleen maar properties van een category tegelijk zien).
Dit kan zeker zijn nut hebben, en ik moet toegeven dat ik het zo nu en dan daadwerkelijk gebruik. Dat er nog wat haken en ogen aan zijn zal ik met name aan het eind nog even toelichten, laten we eerst eens kijken hoe we een eigen property category kunnen maken, en hoe we de Euro, Gulden en BFR properties aan deze category toe kunnen voegen.

Om met het laatste te beginnen: er zijn vier manieren om een property in een property category te stoppen, en ze heten allemaal RegisterPropertyInCategory. De reden dat het er vier zijn heeft uiteraard te maken met method overloading, een feature die met Delphi 4 werd geïntroduceerd.

  type
    TPropertyCategoryClass = class of TPropertyCategory;

    function RegisterPropertyInCategory(
      ACategoryClass: TPropertyCategoryClass;
      const APropertyName: String): TPropertyFilter; overload;
    function RegisterPropertyInCategory(
      ACategoryClass: TPropertyCategoryClass;
      const APropertyName: String;
      AComponentClass: TClass): TPropertyFilter; overload;
    function RegisterPropertyInCategory(
      ACategoryClass: TPropertyCategoryClass;
      const APropertyName: String;
      APropertyType: PTypeInfo): TPropertyFilter; overload;
    function RegisterPropertyInCategory(
      ACategoryClass: TPropertyCategoryClass;
      APropertyType: PTypeInfo): TPropertyFilter; overload;
Het resultaat van de RegisterPropertyInCategory is een zgn. TPropertyFilter (maar die heb je verder niet nodig). Interessant is het te zien dat we deze funktie op vier manieren kunnen aanroepen: met een property naam; met een class type en property name; met property type en property naam; of met property type. En daarbij natuurlijk als eerste argument ACategoryClass (de category waar we de property in willen hebben).
Definities van bestaande property categoriën kunnen we terugvinden in de DsgnIntf.pas unit, en zijn: TActionCategory, TDataCategory, TDatabaseCategory, TDragNDropCategory, THelpCategory, TLayoutCategory, TLegacyCategory, TLinkageCategory, TLocaleCategory, TLocalizableCategory, TMiscellaneousCategory, TVisualCategory, TInputCategory en TMidasCategory (uit MIDREG.PAS).

Om een eigen property category te maken hoeven we slechts een eigen class af te leiden van TPropertyCategory met twee class methods: Name en Description. Het feit dat het class methods zijn heeft als gevolg dat de Object Inspector niet eens een daadwerkelijke instantie van de property category hoeft te hebben om achter de Name te komen (de Description wordt (nog) niet gebruikt, overigens).

De volgende code definieert een nieuwe TDrBob42PropertyCategory met als Name "Geld" (dus prima geschikt voor de Euro, Gulden en BFR).

  type
    TDrBob42PropertyCategory = class(TPropertyCategory)
    public
      class function Name: string; override;
      class function Description: string; override;
    end;

  implementation

  class function TDrBob42PropertyCategory.Description: string;
  begin
    Result := 'DrBob42''s Property Category';
  end;

  class function TDrBob42PropertyCategory.Name: string;
  begin
    Result := 'Geld';
  end;
Met bovenstaande definitie is het simpel geworden om de Euro, Gulden en BFR properties in een eigen category met naam "Geld" te stoppen:
  procedure Register;
  begin
    RegisterPropertyInCategory(TDrBob42PropertyCategory,'Euro');
    RegisterPropertyInCategory(TDrBob42PropertyCategory,'Gulden');
    RegisterPropertyInCategory(TDrBob42PropertyCategory,'BFR');
    RegisterComponents('DrBob42', [TEuro,TEuroEdit]);
  end;
Nu zullen de Euro, Gulden en BFR properties in de category "Geld" staan. Handig in gebruik, toch?

Er zijn een paar potentiële problemen bij het gebruik van property categoriën. Allereerst is het mogelijk om dezelfde naam terug te geven als Name. Dus ik kan de TDrBob42ProeprtyCategory ook "Visual" laten heten (wat niet zo handig meer is). Daarnaast wordt de Description (nog) helemaal niet gebruikt, en die zou bij gelijke namen voor een beetje nadere duidelijkheid kunnen zorgen.
Afgezien daarvan, is de unit DsgnIntf nodig voor het maken en gebruiken van property categoriën. De DsgnIntf.dcu wordt echter niet meer bijgeleverd bij Delphi, en we zullen zelf de DsgnIntf.pas unit uit de Sources/ToolsAPI directory moeten halen. Dat, plus het feit dat we de DsgnIntf.pas unit natuurlijk niet mogen distribueren, maakt het niet envoudig om third-party components te maken die andere Delphi gebruikers eenvoudig kunnen installeren (zonder "handleiding" daarbij).

Natuurlijk zijn de voordelen ook duidelijk: groepering en overzicht, en daarmee potentieel weer tijdwinst. Property Categoriën zijn echt een fijne uitbreiding van de Object Inspector. Toch kan deze nieuwe feature soms voor wat lastige situaties zorgen (de code werkt alleen in Delphi 5, en zelfs dan alleen als iemand de DsgnIntf.pas "in de buurt" heeft). Of deze nieuwe feature het eeuwige leven heeft weet ik ook nog niet; de tijd zal het leren. Vooralsnog geldt: gebruik, maar bedachtzaam en met mate...
Mocht iemand nog vragen, opmerkingen of suggesties hebben, dan hoor ik die het liefst via .


This webpage © 1999-2006 by webmaster drs. Robert E. Swart (aka - www.drbob42.com). All Rights Reserved.